PayPal JS SDK buttons: enable only when a user county is selected - paypal

I want to enable and disable the PayPal button(s) depending on certain user inputs in an input form. Below is part script where the button should only be active when the user has selected a country. I am using a variable to change to 1 when a country is selected, but the action enable is not working.
let payPalBtn_status = 0; // variable set paypal status
$(document).ready(function () {
initPayPalButton(); //iniate button place on DOM
$('#country_shipping').on('change', function(e){
var country = $('#country_shipping :selected').val();
if (country != 'none'){
payPalBtn_status = 1; // if country select has been selected status = 1
}
});
})
function initPayPalButton() {
paypal.Buttons({
onInit: function(data, actions){
actions.disable();
if (payPalBtn_status == 1){
actions.enable(); // if paypal status variable is equal to 1 button to be enabled
}
},
style: {
shape: 'rect',
color: 'gold',
layout: 'vertical',
label: 'paypal',
},
createOrder: function(data, actions) {
return actions.order.create({
purchase_units: [{
"reference_id":"123456789",
"description":"Sticker, ref_id: 1234567",
"amount":{
"currency_code":"GBP",
"value":4,
}}]
});
},
onApprove: function(data, actions) {
return actions.order.capture().then(function(orderData) {
});
},
onError: function(err) {
console.log(err);
}
}).render('#paypal-button-container');
}

Move the synchronous event listener to inside onInit. There is an example in the documentation.
Adapting it from a checkbox to a "#country_shipping" element that has a value...
paypal.Buttons({
// onInit is called when the button first renders
onInit: function(data, actions) {
// Disable the buttons
actions.disable();
// Listen for changes...
document.querySelector('#country_shipping')
.addEventListener('change', function(event) {
// Enable or disable the button when it has a value
if (event.target.value) {
actions.enable();
} else {
actions.disable();
}
});
},

Related

Paypal sandbox window closed on subscribe button click with "create_order_error : Token Failure"

Here is the code to create subscription and user consent from paypal sandbox.
paypal.Buttons({
style: {
shape: 'rect',
color: 'white',
layout: 'horizontal',
label: 'subscribe',
tagline: false,
},
createSubscription: function(data, actions) {
if( subscriber_id !== null ){
return actions.subscription.revise(subscriber_id, {
'plan_id': "xxxxxxxx",
});
}else{
return actions.subscription.create({
'plan_id': "xxxxxxxx",
});
}
},
onApprove: function(data, actions) {
alert("Plan successfully Subscribed");
},
onCancel: function(data){
alert("Payment Cancelled");
},
onError : function(err){
alert("Error on payment");
}
}).render("#paypal_button_container");
It successfully return subscriber ID with this url : https://www.sandbox.paypal.com/v1/billing/subscriptions
Then it open popup window for sandbox url : https://www.sandbox.paypal.com/smart/api/billagmt/subscriptions/I-JM3GEG2DY222/cartid and it immediately close with following "create_order_error"
Object { err: "TOKEN_FAILURE\nd/<#https://www.sandbox.paypal.com/smart/buttons?style.label=subscribe&style.layout=horizontal&style.color=white … }
It was working fine before 28-Oct-2022.
I am facing the exact same issue.
The Sandbox for testing subscription is broken.
I managed to pass the "token failure" this morning and another error message was reporting that the system is not available yet because of an internal problem so I guess the issue is on paypal side and hopefuly they are working on it.
So let's just wait...

Paypal paylater set button amount

I have a paypal page that accepts paypal pay later. I want to dynamically set the button amount with javascript.
This is the code
<script src="https://www.paypal.com/sdk/js?client-id=&currency=GBP&enable-funding=paylater,card&components=messages,buttons">
</script>
<div id="paypal-button-container"></div>
<script>
var amount = 90;
//$('#paypal').data('pp-amount',amount);
paypal.Buttons({
createOrder: function(data, actions) {
return actions.order.create({
purchase_units: [{
amount: {
value: amount
}
}]
});
},
//return url after successful payment
onAuthorize: function(data, actions) {
console.log(data, actions);
actions.payment.execute().then(function(data) {
console.log(data);
// Show a success page to the buyer
});
}
}).render('#paypal-button-container');
</script>
<div id="paypal" data-pp-message data-pp-amount="90"> </div>
I added the paypal id into this <div id="paypal" data-pp-message data-pp-amount="90"> </div>
I am trying to dynamically set this value
data-pp-amount="90"
but this doesn't work $('#paypal').data('pp-amount',amount);
I did it this way
<script src="https://www.paypal.com/sdk/js?client-id=&currency=GBP&enable-funding=paylater,card&components=messages,buttons">
</script>
<div id="paypal-button-container"></div>
<div class="pp-message"> </div>
<script>
var am = 90;
paypal.Buttons({
createOrder: function(data, actions) {
return actions.order.create({
purchase_units: [{
amount: {
value: am
}
}]
});
},
//return url after successful payment
onAuthorize: function(data, actions) {
console.log(data, actions);
actions.payment.execute().then(function(data) {
console.log(data);
// Show a success page to the buyer
});
}
}).render('#paypal-button-container');
paypal.Messages({
amount: am,
placement: 'product',
style: {
layout: 'text',
logo: {
type: 'primary',
position: 'top'
}
}
})
.render('.pp-message');
</script>

PayPal Smart Payment Button: setting an invoice id to avoid duplicate transactions

Sometime a user charged multiple times because of accidental clicks on the pay button in paypal smart payment button. In paypal dashboard > payment preferences I have already enabled the option "Yes, block multiple payments per invoice ID".
Now I want to set the invoice id in my smart button script code, which is as follows:
function initPayPalButton() {
paypal.Buttons({
style: {
shape: 'rect',
color: 'gold',
layout: 'vertical',
label: 'pay',
},
createOrder: function(data, actions) {
return actions.order.create({
purchase_units: [{"amount":{"currency_code":"USD","value":total_amount}}],
application_context: {
shipping_preference: 'NO_SHIPPING'
}
});
},
onApprove: function(data, actions) {
return actions.order.capture().then(function(details) {
window.location = 'success_url';
});
},
onError: function(err) {
console.log(err);
alert('Something went wrong. Please refresh the page and try again.');
}
}).render('#button_container_id');
}
initPayPalButton();
Add invoice_id with a unique identifier from your system to avoid duplicate payments.
See: https://developer.paypal.com/docs/multiparty/checkout/standard/integrate/#link-addpaymentbuttons
Other useful purchase unit parameters include:
A unique invoice_id that hasn't been used for a previously-completed
transaction to identify the order for accounting purposes and to
prevent duplicate payments.
A custom_id value of your choice for your
system or own reference. This value is not indexed or visible to the
buyer.
This is what my code looks like:
paypal.Buttons({
style: {
shape: 'rect',
color: 'silver',
label: 'buynow'
},
onError: function (err) {
// FIXME: show the user an error message
},
onClick: function(data) {
// FIXME: do something cool when the button is clicked
},
// Set up the transaction
createOrder: function(data, actions) {
return actions.order.create({
purchase_units: [{
description: 'My awesome product',
amount: {
currency_code: "USD",
value: 9.99,
breakdown: {
item_total: {
currency_code: 'USD',
value: 9.99
},
discount: {
currency_code: "USD",
value: 1.25
}
}
},
invoice_id: 'UNIQUE-ID',
custom_id: 'ANOTHER-SYSTEM-ID'
}],
application_context: {
shipping_preference: "NO_SHIPPING"
}
});
},
// Finalize the transaction
onApprove: function(data, actions) {
return actions.order.capture().then(function(details) {
// FIXME: finalise the order and show the success message
console.log("order id: "+details.id);
});
}
}).render('#paypal-button-container');
}
In the purchase_units, specify invoice_id.
It's documented here: https://developer.paypal.com/docs/api/orders/v2/#orders-create-request-body

Paypal Custom Payment Amount

I would like to direct my clients to a payment site that allows them to enter the custom invoice amount. I am using the basic Paypal checkout code, however the amount is defaulting to $1. I would like to add a text box to set the amount.
The current value is set to 1 in the code below, is there a way to change this to a manual entry?
<div id="paypal-button-container"></div>
<script src="https://www.paypal.com/sdk/js?client-id=Aff-
dCcKoLWR548gVo8w9nNu1F7Lx0Poo8I1STNdRuxvRYyv3JDrcNqcg3snh7SRmY9BMZdJXm1Ih95y&currency=USD" data-sdk-
integration-source="button-factory"></script>
<script>
paypal.Buttons({
style: {
shape: 'rect',
color: 'gold',
layout: 'vertical',
label: 'pay',
},
createOrder: function(data, actions) {
return actions.order.create({
purchase_units: [{
amount: {
value: '1'
}
}]
});
},
onApprove: function(data, actions) {
return actions.order.capture().then(function(details) {
alert('Transaction completed by ' + details.payer.name.given_name + '!');
});
}
}).render('#paypal-button-container');`enter code here`
</script>
You can use Javascript to get the amount from somewhere else on your site.
value: document.getElementById('myAmountInput').value
Or similar.

Remove shipping address option in PayPal Express Checkout

I am using the JS script recommended by PayPal. It's working well, however it is showing a "Ship to" address of the buyers.
I am trying to search the internet and found that https://api.sandbox.paypal.com/v1/payment-experience/web-profiles/ requested with "no_shipping": 1, can do the trick. But for that we need to make a curl request before the payment.create, so that we can pass it returned id in the function.
Is this possible in JS?
Or is there a much better and simpler way to remove it using the following JS?
<script src="https://www.paypalobjects.com/api/checkout.js" data-version-4></script>
<script>
paypal.Button.render({
env: 'sandbox', // Optional: specify 'sandbox' or 'production'
client: {
sandbox: '{{$data['SandboxId']}}',
production: '{{$data['ProductionId']}}'
},
payment: function() {
var amount = document.getElementById("amount").value;
var env = this.props.env;
var client = this.props.client;
return paypal.rest.payment.create(env, client, {
transactions: [
{
amount: {
total: amount,
currency: "USD",
details: {
subtotal: amount,
tax: "0.00",
shipping: "0.00"
}
},
description: "This is payment description.",
item_list: {
items:[
{
quantity:"1",
name:"Orders",
price:amount,
sku:"product12345",
currency:"USD"
}
],
},
}],
});
},
commit: false, // Optional: show a 'Pay Now' button in the checkout flow
onAuthorize: function(data, actions) {
console.log(data);
alert('confirmation here');
// Optional: display a confirmation page here
return actions.payment.execute().then(function() {
alert('Success here');
// Show a success page to the buyer
});
},
}, '#paypal-button');
</script><div id="paypal-button" ></div>
To expand on Bluepnume's answer, here is a complete example:
payment: function(data, actions) {
return actions.payment.create({
payment: {
transactions: [
{
amount: { total: '1.00', currency: 'USD' }
}
]
},
experience: {
input_fields: {
no_shipping: 1
}
}
});
},
You can pass an experience options like so:
paypal.rest.payment.create({
// payment options here
}, {
// experience options here
});
This is how it needs to be done in ngx-paypal version 11
application_context:
{
shipping_preference: "NO_SHIPPING"
}
ngx-paypal: "^11.0.0"