I'm developing an e commerce website using angularjs in which I'm using paypal checkout https://developer.paypal.com/docs/integration/direct/express-checkout/integration-jsv4/script-option... for paypal integration. When a user click's paypal rendered button, it is supposed to open a new popup window in which paypal login and payment is made, and then user is redirected to our app with payment details. The app seems to work fine in chrome, edge and even IE for that matter (although IE has different issue with the flow), but in firefox, the popup modal is not triggering at all. No console errors, which has made it very difficult to solve. Made a lot of research (google search :-p) but couldn't fix it. Please anyone help me, thanks.
Here is my script js for paypal
// Paypal
paypal.Button.render({
env: 'sandbox', // Environment: 'sandbox' or 'production'
// Pass the client ids to use to create your transaction on sandbox and production environments
client: {
sandbox: 'xxxxxx', // from https://developer.paypal.com/developer/applications/
production: 'xxxxxx' // from https://developer.paypal.com/developer/applications/
},
// Pass the payment details for your transaction
// See https://developer.paypal.com/docs/api/payments/#payment_create for the expected json parameters
payment: function() {
return paypal.rest.payment.create(this.props.env, this.props.client, {
transactions: [{
amount: {
total: 25.00,
currency: 'USD'
}
}]
});
},
// Display a "Pay Now" button rather than a "Continue" button
commit: true,
// Pass a function to be called when the customer completes the payment
onAuthorize: function(data, actions) {
return actions.payment.execute().then(function() {
console.log('The payment was completed!');
});
},
// Pass a function to be called when the customer cancels the payment
onCancel: function(data) {
// console.log('The payment was cancelled!');
}
}, '#paypal');
And html for rendering button
<button type="button" id="paypal"></button>
Related
I have a website with multiple payment forms. I can switch between them and then I have a button with "Continue to checkout" label that when you click, it does something depending on the payment method chosen. The handler function looks something like this:
const handlePayment = (method) => {
if(method === paymentMethods.STRIPE){
// do something
}
if(method === paymentMethods.PAYPAL){
// do something else
}
}
The problem is I looked at the docs and it's always about showing a PayPal button, I don't want a PayPal button, I want to open the PayPal form directly from my button, when a method is selected.
So want I mean is, I want to do it programmatically. Is there any way to do this? I don't want to do a hacky solution hiding the button or triggering the click or some weird thing...
The React PayPal component is just a wrapper for the JS SDK.
My UI looks something like this: I'd like to open the PayPal payment form when I click on Pay, only if PayPal is selected.
If you use the PayPal JS SDK to open the checkout, you have to use its button, and the user has to click it themselves. PayPal does this intentionally so that the button shown uses their consistent branding.
If you want an alternative, you can integrate without the JS SDK (REST API only) and have your own button which redirects to the PayPal page for approval, which will then return to your site. This is an old integration pattern, for old websites, and not recommended.
Despite your misgivings and desire not to use it, the JS SDK and its button in a container sized to your requirements is in fact the best available solution.
Based on the UI shown, what you might op to do is hide your "Pay" button and replace it with one that says "Pay With PayPal" when that method is selected, which could look like this (sized to fit your container):
Here's sample HTML/JS for that, you can do the same from react-paypal-js :
<script src="https://www.paypal.com/sdk/js?client-id=test¤cy=USD"></script>
<div id="paypal-button-container"></div>
<script>
paypal.Buttons({
fundingSource: paypal.FUNDING.PAYPAL,
style: {
color: "blue",
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>
I need only one Payment Method (AliPay). But I can't disable default payment method with Stripe Checkout (Credit Card). Of course, I read documentation, but I don't have any idea how I can make that.
This is My code.
var handler = StripeCheckout.configure({
key: 'public_key',
alipay: true,
locale: false,
currency: "usd",
token: function(token) {
// Use the token to create the charge with a server-side script.
// You can access the token ID with `token.id`
}
});
handler.open({
name: 'example.com',
description: 'AliPay Payment',
amount: 10000
});
Thanks!
It's not possible to disable the default (card) area of Checkout.
If you're looking for greater customizability of your payment form I'd have a look at Stripe.js/Elements and the Sources API. You can use the Sources
to generate an AliPay source, redirect a user to AliPay to authorize a payment, and then return them to your site, https://stripe.com/docs/sources/alipay
I'm currently working on a PayPal Express checkout integration using the Client-side JS approach for taking payments. I'm looking to utilise their "Negative Testing" feature to try to simulate potential errors and provide appropriate responses to the customer.
Just a reference to the relevant doc page here for reference
It seems to enable negative testing you need to pass an extra header along with the the payment request specifying the particular error you would like to trigger for that payment.
This is my current JS for setting up the transaction:
<script>
//We need to convert our generated json string into a bonified javascript object
var paypal_transaction = JSON.parse(JSON.stringify(<?php echo $paypal_json; ?>));
paypal.Button.render({
env: 'sandbox', // 'production'/'sandbox',
commit: true, // Show a 'Pay Now' button - Allows us to capture the payment right away
client: {
sandbox: 'Ab_hPp7h70DoFKChLMSynNxacQQbGcb_tP1cDbzW9jC6a0rYIZH0CkEYYfkw6csvmlyTmfLnagelqB85',
production:''
},
//How we want the button to look
style: {
size: 'responsive',
color: 'gold',
shape: 'rect',
label: 'pay'
},
headers: {
'{"mock_application_codes":"INSTRUMENT_DECLINED"}'
}
payment: function(data,actions) {
return actions.payment.create({
//Pass our created transaction to paypal.
payment:paypal_transaction,
/**
* We have to set the following fields to prevent the client from
* changing their delivery address when they're at PayPal
*/
experience: {
input_fields: {
no_shipping: 0,
address_override:1
},
}
});
},
onAuthorize: function(data, actions) {
/**
* [description]
* #param payment - The authorised transaction returned from paypal
* #return redirect - We redirect the cutomer to our confirmation page as soon as we return from PayPal as we're confident we have the correct
*/
return actions.payment.execute().then(function(payment) {
actions.redirect();
});
},
onError: function(err) {
console.log(err);
// Show an error page here, when an error occurs
},
onCancel: function(data, actions) {
return actions.redirect();
// Show a cancel page or return to cart
}
}, '#paypal-button');
Essentially my question is where do I specify the mock application codes like this in the above implementation.
In the docs they give an example cURL request with the below as the extra header that needs to be passed:
"PayPal-Mock-Response:{\"mock_application_codes\":\"INSTRUMENT_DECLINED\"}"
I just don't know how to do this via the JS approach. Can negative testing only be used with a server side implementation?
Hope that's all clear enough!
Had similar issue myself, and the official answer I got was that it is not available:
"I understand this is a frustrating situation. Unfortunately we do not
have any way to offer negative testing for client side integrations.
It may possible for you to do so using Postman, however, we do not
have documentation to offer."
This is really sad though, other payment providers have fixed card numbers for certain error scenarios for example, or have special payment value based codes. PayPal only has that for the Payflow integration, and the request header based mocking stuff is also only possible if you are directly calling their REST APIs.
PayPal is really lame in these aspects, as even if you are mocking behavior with server integration (not that hard, for this at least they have proper code examples), this mocking is explicit and you control the error. If it would be implicit, and originate from an actually validated but invalid card for example, it would be more realistic.
I am using Stripe's custom integration, I know in their example they are adding an event listener, but in my javascript code I am skipping that, not sure if that is why the loading indicator never goes away when someone closes out of it.
Here is my code:
var handler = StripeCheckout.configure({
key: 'tests',
image: 'https://stripe.com/img/documentation/checkout/marketplace.png',
locale: 'auto',
token: function(token) {
// You can access the token ID with `token.id`.
// Get the token ID to your server-side code for use.
},
closed: function() {
// Close Checkout on page navigation:
closehandler();
}
});
handler.open({
name: 'Jungle Exchange',
description: 'Get your Amazon On!',
amount: amount
});
function closehandler() {
handler.close();
}
When clicking on the x for the modal, the loading icon does not disappear from the center of the screen and overlays everything. Any thoughts?
Thanks!
That seems unexpected! I'd recommend writing into Stripe support with the exact URL with this happened and different things you've tried, as well as any errors in your Web Inspector console.
https://support.stripe.com/email/login
I'm trying to integrate Amazon Payments (Payment only, not login with Amazon) into my site.
I can successfully display the authentication form for the payment:
<div id="AmazonPayButton" />
#{
var callbackurl = string.Format("{0}://{1}/Account/AmazonConfirm", Request.Url.Scheme, Request.Url.Authority);
}
<script type="text/javascript">
OffAmazonPayments.Button("AmazonPayButton", "M_MYSELLERID_1234567", {
type: "PwA",
size: "medium",
authorization: function() {
loginOptions =
{scope: "payments:widget", popup: true };
authRequest = amazon.Login.authorize(loginOptions, "#(callbackurl)");
},
onError: function(error) {
alert('We could not connect to Amazon to process your payment, try again later');
}
});
</script>
</div>
Amazon successful redirects to my callback URL after authentication. But when I try to display the wallet widget with the Same Seller ID, I get an "invalid seller ID" error:
<div id="walletWidgetDiv">
</div>
<script>
new OffAmazonPayments.Widgets.Wallet({
sellerId: 'M_MYSELLERID_1234567',
onReady: function(billingAgreement) {
var billingAgreementId = billingAgreement.getAmazonBillingAgreementId();
},
agreementType: 'BillingAgreement',
design: {
size : {width:'400px', height:'260px'}
},
onPaymentSelect: function(billingAgreement) {
// Replace this code with the action that you want to perform
// after the payment method is selected.
},
onError: function(error) {
alert(error.getErrorMessage());
}
}).bind("walletWidgetDiv");
</script>
Why would the authentication work, only to have the Wallet display rejected?
Update #Brent Douglas in his answer triggered me to recheck my seller ID and I had specified an incorrect ID in one of my script references. Now I get the following error:
"the seller ID is not in the appropriate state to execute the request"
Not sure what that means. I checked my account and the deposit/banking info is specified, and nothing else is flagged on the Integration Settings page. Is there anything else in the account that needs to be added/verified? (Other than the typical, web page URL and other info)
You need to log in to your Seller Central account, make sure "Amazon Payments Advanced" is selected in the drop-down at the top, click "Settings" in the upper right, then "Integration Settings". On this page you will see "Your Merchant ID". This is your Seller ID. Replace M_MYSELLERID_1234567 with this seller ID everywhere.
Assuming you are using the correct seller ID you also need to make sure you are including the following in your handle login page where you display the wallet widget.
<!-- since you are using 'popup' -->
<script type='text/javascript'>
window.onAmazonLoginReady = function () {
amazon.Login.setClientId('[YOUR_CLIENT_ID]');
amazon.Login.setUseCookie(true);
};
</script>
You then need to include the Widgets.js file.
For sandbox mode you would use this.
<script src='https://static-na.payments-amazon.com/OffAmazonPayments/us/sandbox/js/Widgets.js'></script>
For production you would use this.
<script src='https://static-na.payments-amazon.com/OffAmazonPayments/us/js/Widgets.js'></script>
I searched around with the same exact error and I found this link.
Which suggest "You need to use SandBox credentials for Amazon Payments. "
Check this link.