Apple Pay completeMerchantValidation cancels session - applepay

My backend successfully validates the merchant and a session is returned, but when I complete the validation on the browser, it immediately cancels the transaction. There are a few similar complaints on the Apple Dev forum, but none seem to have been answered; I'm hoping you guys can help!
Out of all the event handlers on the ApplePaymentSession object, only onvalidatemerchant is called, then as soon as completeMerchantValidation with a valid session object (see payload below), oncancel is triggered.
Session config (on browser)
const session = new ApplePaySession(3, {
currencyCode: 'GBP',
countryCode: 'GB',
merchantCapabilities: [ 'supports3DS' ],
supportedNetworks: ['visa', 'masterCard', 'amex', 'discover' ],
total: {
type: 'final',
label: 'My Product',
amount: 9.99,
},
});
Request (on backend)
{
merchantIdentifier: 'merchant.MY.FQDN',
displayName: 'My Company Name',
initiative: 'web',
initiativeContext: 'MY.VERIFIED.FQDN',
}
Response (from Apple to backend, then sent to completeMerchantValidation
{
"epochTimestamp": 1552090296444,
"expiresAt": 1552093896444,
"merchantSessionIdentifier": "LONG_STRING",
"nonce": "XXXX",
"merchantIdentifier": "SAME_AS_IN_MY_MERCHANT_ID_CERT",
"domainName": "MY.VERIFIED.FQDN",
"signature": "XXXXXX-VERY-LONG-STRING-XXXXX"
}
I'm definitely sending this response into completeMerchantValidation as a JSON object and not a string, like so:
console.log('session is a', typeof(result), result); // says: object
session.completeMerchantValidation(result);
The domain name this is all happening from (and hosted on Firebase) is verified against this Merchant ID and I don't get any errors either in the backend or the browser console, no exception is thrown to catch, it just shows the Apple Pay tray, then says "Payment not complete" and hides the tray very quickly. Help!
UPDATE: Looking at the docs, it appears that startSession (which is being returned by onvalidatemerchant is being phased out, so I have tried replacing it with paymentSession (e.g. https://apple-pay-gateway-nc-pod5.apple.com/paymentservices/paymentSession); but I still get the same response and behaviour.

This solution may or may not work for you, but I was experiencing the same issue in that the session was being cancelled as soon as session.completeMerchantValidation() was called.
It boiled down to the merchantSession being created with a domainName value that was not verified (see: https://developer.apple.com/documentation/apple_pay_on_the_web/configuring_your_environment)
I used a local webserver broadcasting through Ngrok to validate a temporary URL by putting the apple-developer-merchantid-domain-association.txt file where it needed to be based on Apple Pay documentation.
After that, as long as I was using a sandbox iCloud account and a test Apple Pay card, passing the ngrok URL as the domainName value for the merchantSession request worked and Apple Pay finally started working locally. Note that I had to interact with my locally running web application through the ngrok url for Apple Pay to work.

I had the same issue where the payment sheet would display then go away without a chance to authorize the transaction. I made sure the domain was verified, the certificate was valid, and that I was actually receiving a response back from the server side request to Apple. Sorting through the process of elimination I came across certain interesting observations:
If the payment sheet disappeared immediately, it was usually due to a configuration issue with the server side request payload (for example, the "initiativeContext" was "something.com" when I was actually using "www.something.com" in the web browser address).
If the payment sheet disappeared after several seconds, it was usually due to a syntax issue or error in the client side JavaScript. In my case, I was not doing session.onpaymentmethodselected and session.completepaymentmethodselection correctly. So I removed all other Apple specific JS functions except for session.onvalidatemerchant and a subsequent call to session.completeMerchantValidation passing the Apple response from the server side request. It then worked.
If the Apple response from the server side request was in any way (even just the casing) changed from what Apple originally sent it would not work (for instance, "epochtimestamp":1668095263534," vs "epochTimestamp":1668095263534,").
Hope that helps.

Related

Getting 'name_taken' error when creating new Slack channel via API, despite no channel with that name

I'm receiving a name_taken error when creating a slack channel via the API using the conversations.create endpoint. My code was working fine up until a couple days ago, but now I get that error no matter what slack workspace I am in, even a brand new one that has no channels other than default ones. The Slack API docs say that the error means "A channel cannot be created with the given name," so it likely isn't because there is already a channel with that name, but I have no idea what else would cause this issue. I also tried testing it in Postman, and I get the same error.
However, if I make the channel name I want to create gibberish, it works. This leads me to believe that it has more to do with my slack configuration than my API request, but I am at a loss as to how. I would really appreciate any help someone could provide. Below is the code that makes the API call, as well as the response I get. Thanks in advance.
Request:
const channelName = 'moxified'
const createdChannel = JSON.parse(await request.post(`https://slack.com/api/conversations.create`, {
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: `token=${slackTokenResponse.authed_user.access_token}&name=${channelName}`, //name may change
}));
Response:
{ok: false, error: 'name_taken'}
After reaching out to a Slack developer, they explained that the interference was coming from the fact that my bot's name was also 'moxified'. To quote them, "Channel namespaces can be taken up by user groups as well as a name of a bot." I still don't get why it was working for so long without issue, but I hope this helps someone else one day :)

shopify, making an ajax request from client side

I am making an app for shopify, that would allow costumers to send a message to a sites owner.
For this i have made a little server that would send the email on a post request.
Naturally, shopify would not let me do this. Instead, I am getting a cors, cross origin request issue. So I have created a private app, but they don't appear to provide me with the ability to make a post request to my server.
So I am looking into making a public unlisted app. But I am a bit burned out from my last attempt and am not in the mood to go off implementing oauth (for the first time) just to find out that I am still not getting the functionality that I need.
Can anyone please tell me what are the minimum requirements for me to be able to whitelist my server for ajax requests from the client side?.

Safari on iOS 11.4 not sending cookies on POST requests

I've been using the same code for years and things have been working very well on every browser so far:
$.ajax({
url: '/test.php',
data: parameters,
dataType: 'html',
type: 'post'
})
However, since my users started to upgrade to iOS 11.4, those who use the Private mode of Safari are having an issue with "being disconnected" from my website.
This is because ajax POST requests aren't sending any Cookies, apparently. A whole new session is created as part of that POST request (new cookies created, etc).
However, that doesn't affect anything on the GET requests themselves. They stay with the same cookies (and therefore same session), even though new cookies were set as part of the ajax POST request. It's like those ajax POST requests are "sandboxed", not affecting anything else.
Any ideas? Is this a bug on Safari on iOS 11.4 ?
We worked through a similar issue and figured out that it was actually related to Service Workers. From what I can tell, it's a bug in the latest version of Safari's implementation of Service Workers that causes some cookies not to be passed on POST in Private mode. For now, we have disabled our Service Worker and site functionality has returned to normal for those users.
Not sure if this is your problem or not, but it sounds very similar. Hope this helps!

Mobile device doesn't use cookie

For some reason the mobile authentication detection stoped working. When I access a location containing a form on my page, the form should call (via ajax) for additional information to fill the fields, the server returns depending on user authentification. It worked well for nine months, but stoped working for mobile devices, however it still works for desktop browser access. Mobile and desktop use exactly the same access route, arguments, urls, view function ... everything. The one difference that I noted (after some 8 hours on this issue) when I looked up the request.META, is that desktop sends cookie information, mobile doesn't. However cookies are enabled on mobile and desktop browser. I tested this with Chrome mobile and (a freshly installed) Firefox on mobile, the result is exactly the same.
How is this possible? Why does the form when initializing on desktop send the cookie info and when initializing on mobile don't send it?
Here is a previous version of this question (written before I noticed the cookie difference and thought it was an api issue) containing technical details that I don't consider to be relevant for the particular question of how does the same functionality behave some differently on mobile and desktop.
EDIT: I really don't know what code to show, but probably the ajax request could be relevant. I am really lost here. This is the react-js service I use to load form initials, it's the one that arrives without cookie information when send form mobile device, and with cookie if send from desktop device, to the server. I am not aware to have added anything or changed this in anyway in the past nine months, it always worked only like this:
loadFormInitials = (typ,genderRelevant,auth) => {
$.ajax({
url: UserConstants.BASE_URL+'elements/?item=setup&auth='+auth,
method: 'GET',
dataType: 'json',
success: (result) => {
var data = JSON.parse(result.initial_data);
FormActions.loadFormInitialsAction(data,typ,genderRelevant);
});
}
Mobile companies sometime alter HTTP requests with their heavy caching.
You'd probably want to try again with HTTPS requests, not sure it'll fix though.

AWS S3 static website ajax callback fails

Recently I got to the point to host a static webpage with a subscription option on aws s3 while website development is undergoing. My static web page makes an ajax call to another RESTful service with an email of a subscriber as a parameter. When subscription is done I need to notify a subscriber. Here it seams an issue with the callback.
$.ajax({
type: 'GET',
url: 'http://www.my-domain.com/api/Subscribe?email=' + email
}).success(function (data) {
if (data) {
alert('Thank you for registering!');
}
});
After subscription is done ".success(" doesn't fire up. Response on the request is:
Reload the page to get source for: http://www.my-domain.com/api/Subscribe?email=john.smith#simplyemail.com
Does anyone know if it's an s3 feature or something else?
As per your description this seems to be related with CORS policy.
Look to "why CORS" as Amazon defines it:
In order to keep your content safe, your web browser implements something called the same origin policy.
The default policy ensures that scripts and other active content
loaded from one site or domain cannot interfere or interact with
content from another location without an explicit indication that this
is the desired behavior.
In certain cases, the developer of the original page might have
legitimate reasons to write code that interacts with content or
services at other locations. CORS provides the mechanism to allow the
developer to tell the browser to allow this interaction.
I understood that:
[...] ajax call to another RESTful service[...]
Means call to another server, and this may be blocked by Browser because of CORS.
References:
Mozilla
W3C

Resources