Amazon Payments: Successful auth, fails on wallet display - javascript

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.

Related

nodeJS Paypal REST API to revise plan give broken but working link

I'm trying to integrate Paypal into my app in NodeJS. I'm using REST API since the official npm packet is deprecated.
Let's suppose I have a product with two plans, planA and planB, necessary for recurring payments like subscriptions. Suppose a customer subscribe to planA, which costs 10$. After a while, he wants to switch to planB, which costs 20$, to unlock premium content in the platform.
I found the API: POST/v1/billing/subscriptions/{id}/revise
with which one should be able to send the planID planB to switch to it. You can also send effective_time field to specify when the change is effective. After calling this API, Paypal reply with 6 links, and I use the first (approve) to redirect the customer to Paypal domain to confirm it's will to switch the plan. After the user login, confirm and click "Accept and subscribe" to the new plan, the page always give me the following error: Things don't appear to be working at the moment. Please try again later.
, despite the plan change goes fine (I can verify it through dashboard).
I'm wondering what can I do to avoid that error.
I want to clarify that in the settings, through the dashboard, under Account settings -> Website payments -> Website preferences, I temporarily have the option Block non-encrypted website payment to Off.
Thank you all in advance!
The setting "Block non-encrypted website payment" is not relevant to this issue, and will have no effect. It applies exclusively to legacy HTML-only payments, which you should not concern yourself with.
Edit: ah yes, a redirect integration requires an application_context with a return_url. For usage with the SDK, no redirect_url is used, hence why the field is not required by the API.
Previous answer follows:
The issue you describe seems to be a problem with the PayPal site, and possibly only occurs in sandbox mode or with certain browsers/cookies. You can test as desired and contact PayPal's support if needed.
It is also possible to do a revise with the JS SDK rather than a redirect. For a client-side-only integration (no API), this can be done using actions.subscription.revise. Search for that text within the SDK reference.
To combine the JS SDK with the API call you are using, have your button code fetch the revised subscription ID from your server. Here is a sample for a create, which you can adapt to be a revise as it's essentially the same thing (you'd just likely be using a /revise endpoint /path/on/your/server)
<script src="https://www.paypal.com/sdk/js?client-id=..........&vault=true&intent=subscription"></script>
<div id="paypal-button-container"></div>
<script>
paypal.Buttons({
style: {
label:'subscribe' //Optional text in button
},
createSubscription: function(data, actions) {
return fetch('/path/on/your/server/paypal/subscription/create/', {
method: 'post'
}).then(function(res) {
return res.json();
}).then(function(serverData) {
console.log(serverData);
return serverData.id;
});
},
onApprove: function(data, actions) {
/* Optional: At this point, notify your server of the activated subscription...
fetch('/path/on/your/server/paypal/subscription/activated/' + data.subscriptionID , {
method: 'post'
}).then(function(res) {
return res.json();
}).then(function(serverData) {
//
});
*/
//You could additionally subscribe to a webhook for the BILLING.SUBSCRIPTION.ACTIVATED event (just in case), as well as other future subscription events
//Ref: https://developer.paypal.com/docs/api-basics/notifications/webhooks/event-names/#subscriptions
// Show a message to the buyer, or redirect to a success page
alert('You successfully subscribed! ' + data.subscriptionID);
}
}).render('#paypal-button-container');
</script>

Blocked a frame from accessing a frame with origin "https://www.paypal.com". Protocols, domains, and ports must match. What does this mean?

I have a website that I am using the PayPal smart buttons in. When testing it in the Sandbox environment it worked perfectly but when I changed the Client ID from the Sandbox one to the Live Client ID, the Payments will not go through.
The PayPal buttons still render and it still takes you to the checkout window and still allows you to Pay, but when you click the payment button, the window closes and the buyer gets an email saying that PayPal found some risks associated with the payment? Click the PayPal buttons, in the JavaScript console log I get this error 3 times:
Blocked a frame with origin "https://www.mobilemastersshop.com" from accessing a frame with origin "https://www.paypal.com". Protocols, domains, and ports must match.
Is this why it won't work and if so how do I fix it? I am using an SSL certificate from Let's Encrypt so the URL is secure but do I need to change anything in the .htaccess file for PayPal to work?
After Comments
I think the issue is that is didn't this section:
But I do not know where to include these vars. My PayPal button render code is:
<script>
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": applyDiscount(),
"currency_code": "USD",
"breakdown": {
"item_total": {
"currency_code": "USD",
"value": applyDiscount()
},
},
},
"items": PayPalItems()
}
]
});
},
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 completed by ' + details.payer.name.given_name);
window.location.href = "orderConfirmed.php";
clearCart()
});
}
}).render('#paypal-button-container');
//This function displays Smart Payment Buttons on your web page.
</script>
I guessed that the vars have to go in this script so my Live Client ID script looks like this:
<script src="https://www.paypal.com/sdk/js?client-id=AU25a1zm8IuMS_HHl-90AUaHjQBdA-TnzsaSkF2do60t7VS8IukeuBhUY552W1pY_CE0QIY2h9i5p1cK">
// Add your client ID and secret
let PAYPAL_CLIENT = 'AU25a1zm8IuMS_HHl-90AUaHjQBdA-TnzsaSkF2do60t7VS8IukeuBhUY552W1pY_CE0QIY2h9i5p1cK';
let PAYPAL_SECRET = 'EIwsaGfAw7tiNBJBBb7jVWxrH6fqSLJ0fg-oNAJ-pQc37nM0ndSwqN6L0tRIvrNv9y5l2rXJdw914NUE';
// Point your server to the PayPal API
let PAYPAL_ORDER_API = 'https://api.paypal.com/v2/checkout/orders/';
</script>
<script src="https://www.paypal.com/sdk/js?client-id=AU25a1zm8IuMS_HHl-90AUaHjQBdA-TnzsaSkF2do60t7VS8IukeuBhUY552W1pY_CE0QIY2h9i5p1cK">
// Add your client ID and secret
let PAYPAL_CLIENT = 'AU25a1zm8IuMS_HHl-90AUaHjQBdA-TnzsaSkF2do60t7VS8IukeuBhUY552W1pY_CE0QIY2h9i5p1cK';
let PAYPAL_SECRET = 'EIwsaGfAw...redacted';
// Point your server to the PayPal API
let PAYPAL_ORDER_API = 'https://api.paypal.com/v2/checkout/orders/';
</script>
A client-side integration only uses a client-id, which is on the first script line. All the other information you added in is for a server-side integration, is not used here, and so is not needed.

nodejs facebook messenger bot admin or editor id instead of page id

i'm using bottender & nodejs to create a bot messenger , but i got a problem when i try to retrieve the user id of a (admin or editor) in my page to know who send the response to a user in the page.
this is what i got :
{ sender: { id: '868761280555360' },
recipient: { id: '787381751469' },
timestamp: 1515780811774,
message:
{ is_echo: true,
mid: 'mid.$cAAUU4wBJk8VnHNjz_lg65PqOOZXZ',
seq: 361916,
text: 'hi' } }
sender : is the id of page and not the admin id for example.
recipient: user id who contact the page.
any one has a idea how i can get a sender id (admin or editor) of a page instead of page id with bottender.
The message was sent from the actual page. Even if there is an admin or editor who sent the message, he was using the page's identity, therefore is not possible to detect who actually sent the message.
You could tell your admins or editors to use a signature in the message. Split the message and get the admin's name.
You won't be able to get the sender behind the page, as facebook offcial docunment stated, here's a receiveing text message webhook event example:
{
"sender":{
"id":"<PSID>"
},
"recipient":{
"id":"<PAGE_ID>"
},
"timestamp":1458692752478,
"message":{
"mid":"mid.1457764197618:41d102a3e1ae206a38",
"text":"hello, world!",
"quick_reply": {
"payload": "<DEVELOPER_DEFINED_PAYLOAD>"
}
}
}
ref:
https://developers.facebook.com/docs/messenger-platform/reference/webhook-events/messages
https://developers.facebook.com/docs/messenger-platform/reference/webhook-events/message-echoes
BTW, you can always check the rawEvent received when using bottender, with context.event.rawEvent.
It would be helpful sometimes.

How to retrieve the Azure Active Directory logged in user information from Javascript?

I have a web app where the client side is developed in Javascript. I have already enabled Azure AD login for my app by configuring it at portal.azure.com. Then, every time when this app loads, users are required to log in, if they have not.
I would like to have some Javascript in my client side so the app knows the user name. Here is the code I have.
<script src="https://secure.aadcdn.microsoftonline-p.com/lib/1.0.11/js/adal.min.js"></script>
<script type="text/javascript">
var authContext = new AuthenticationContext({
clientId: 'xxxx-xxx-xxxx',
postLogoutRedirectUri: window.location
});
var user = authContext.getCachedUser();
if (user) {
window.alert("Signed in as " + user.userName);
} else{
window.alert("Failed to get the user information");
}
</script>
However, the variable user is always null. Can anybody help?
That seems you are using "Authentication / Authorization" feature of azure app service and the identity provide is azure ad . If you want to access the tokens from a client (like JavaScript in a browser), or if you want to get a richer set of information about the logged in user, you can also send an authenticated GET request to the /.auth/me endpoint. Javascript code below to get user claims is for your reference:
<script type="text/javascript">
$(document).ready(function ()
{
$.get("https://xxxxxx.azurewebsites.net/.auth/me", function (data, status) {
for (var key in data[0]["user_claims"]) {
var obj = data[0]["user_claims"][key];
alert(obj["typ"]); //claim type in user_claims
alert(obj["val"]) //claim value in user_claims
}
});
});
</script>
Thanks, Yan. That pretty solves my problem, only with little revision to your code. My situation is that I need to retrieve the user name first before generating the later part of my app. So, I removed the outer wrapper $(document).ready(function(){}. Correct me if I am wrong. Probably this out wrapper is telling this chunk of code to run after the entire app is loaded. Then, the final code is like this:
<script src="https://code.jquery.com/jquery-1.11.3.js"></script>
<script type="text/javascript">
$.get("https://xxxxx.azurewebsites.net/.auth/me", function (data) {
labeler = data[0]['user_id'];
window.alert("You logged in as " + data[0]['user_id']);
});
</script>

LinkedIn Share API returning "Bad Request" error

I'm trying to implement the LinkedIn share API an I can't figure this one out, since the reply doesn't really tell what's going on.
I've implemented this simple code on my website
<script type="text/javascript" src="//platform.linkedin.com/in.js">
api_key: xxx
authorize: true
lang: de_DE
</script>
<script type="text/javascript">
// Handle the successful return from the API call
function onSuccess(data) {
console.log(data);
}
// Handle an error response from the API call
function onError(error) {
console.log(error);
}
function shareToLinkedIn(){
var payload = {
"content": {
"title": "Test title",
"description": "test description",
"submitted-url": "http://www.someurl.com",
"submitted-image-url": "http://someurl.com/somepic.png"
},
"visibility": {
"code": "connections-only"
}
};
IN.API.Raw("/people/~/shares?format=json")
.method("POST")
.body(JSON.stringify(payload))
.result(onSuccess)
.error(onError);
}
</script>
I'm calling this function via an onClick-event:
<a id="linkedin" href="#"onClick="shareToLinkedIn()"><i class="fa fa-linkedin-square" aria-hidden="true"></i> LinkedIn Test</a></li>
But all I'm getting is the following response: Object {errorCode: 0, message: "Invalid arguments: {S_400_BAD_REQUEST=Bad request}", requestId: "4JVTZJFVF1", status: 400, timestamp: 1467381898243}
Answer to this: You need to implement a login button on your site as well, it's not enough just to be logged in to the LinkedIn-Site.
So, on the site where you "share app" is implemented, add:
<script type="in/Login"></script>
After that, click the button, authorize the app and it should work.
You know, you can actually solve this problem without using the share plugin at all. In fact, just look at the LinkedIn Developers Homepage: "Share on LinkedIn" link. It no longer goes to the old LinkedIn documentation, which has broken styles, broken js, broken HTML, and missing images. It redirects to the Microsoft LinkedIn Share URL Documentation. If the LinkedIn share plugin isn't deprecated, it's certainly no its way there!
You can ditch the LinkedIn Share Plugin altogether. All you need, according to the Microsoft LinkedIn documentation, is the following...
https://www.linkedin.com/sharing/share-offsite/?url={url}
Wish you knew about these URLs changing and evolving without having to track them down yourself? I maintain a project on GitHub to do just that. Check us out! Social Share URLs

Categories