最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - iOS 13 Apple Pay button click throws error: "Must create a new ApplePaySession from a user gesture handler

programmeradmin7浏览0评论

Working on a website that has been integrated with Apple Pay for about a year now with no issues. We are noticing that we are always getting an error now for iOS 13 devices only. iOS 12 and under all work as expected.

Front end click handler:

<div class="btn btn-apple">
  <div class="apple-pay-button apple-pay-button-white" lang="en" data-bind="click: intializeApplePaySession"></div>
</div>

JS click handler:

self.intializeApplePaySession = function() {
  new RestClient(RestClient.POST, "/rest/model/someController", {},
    //Success
    function(data, textStatus, jqXHR) {

      var session = new ApplePaySession(3,data.applePayPaymentRequest);
      initializeCallbacks(session);
      session.begin();
    },
...

"Must create a new ApplePaySession from a user gesture handler." is always thrown at

var session = new ApplePaySession(3,data.applePayPaymentRequest);

for all iOS 13 devices. iOS 12 and below work fine with the same code.

From my debugging I can see that the event being handled is a MouseEvent which makes sense to me. Any ideas as to why this is being thrown?

Working on a website that has been integrated with Apple Pay for about a year now with no issues. We are noticing that we are always getting an error now for iOS 13 devices only. iOS 12 and under all work as expected.

Front end click handler:

<div class="btn btn-apple">
  <div class="apple-pay-button apple-pay-button-white" lang="en" data-bind="click: intializeApplePaySession"></div>
</div>

JS click handler:

self.intializeApplePaySession = function() {
  new RestClient(RestClient.POST, "/rest/model/someController", {},
    //Success
    function(data, textStatus, jqXHR) {

      var session = new ApplePaySession(3,data.applePayPaymentRequest);
      initializeCallbacks(session);
      session.begin();
    },
...

"Must create a new ApplePaySession from a user gesture handler." is always thrown at

var session = new ApplePaySession(3,data.applePayPaymentRequest);

for all iOS 13 devices. iOS 12 and below work fine with the same code.

From my debugging I can see that the event being handled is a MouseEvent which makes sense to me. Any ideas as to why this is being thrown?

Share Improve this question asked Oct 4, 2019 at 19:58 Paul HokePaul Hoke 1451 gold badge2 silver badges7 bronze badges
Add a comment  | 

4 Answers 4

Reset to default 7

We are evolving away from letting websites make cross origin calls without the user's input.

One of the ways this has been locked down for a while is that you can't fire, for instance, a submit button for a form... unless you do it from a click() handler. So you can put a big shiny "Buy now" image on the page and submit the form from clicking on that image, but you can't just do a setTimeout(form.submit(), 100)

I think you've got the same class of thing going here. The REST call is in the click handler, but the apple pay call is in the callback to the REST call, and therefore not really in the click() handler.

Of course you're using the REST call to generate the data to pass to Apple. You may have to generate that data speculatively. But before doing that infrastructure work, I'd experiment with whether an async version of your click handler passes their sanity checks.

Working snippet following discussion with Jason and Brother Woodrow

Synchronous function to call backend and get current cart details. The reason we previously had this in the success callback is because we are using a SPA framework so the cart can change at any time. We cannot call this when the page loads or the data may be stale.

self.getApplePayData = function() {
  var self = this;
  new RestClient(RestClient.POST, "/rest/model/getApplePayPaymentRequest", {},
    function(data, textStatus, jqXHR) {
      self.applePayData = data;
    },
....

 self.intializeApplePaySession = function() {
  var self = this;
  self.getApplePayData();
  var session = new ApplePaySession(3,self.applePayData.applePayPaymentRequest);

I think the key issue is that we were creating a new ApplePaySession from within the success callback of the rest call which Apple does not seem to want to be possible anymore.

Reference from the official documentation

You attempt to create the ApplePaySession outside of a user gesture handler. The exception error "Must create a new ApplePaySession from a user gesture handler" appears.

So in your case, you must create an apple pay session like

session = new window.ApplePaySession(version, request);

then create a request to the server and receive a response.

const data = async getSomeCheckoutData();

and you can proceed with payment throw apple pay

...
session.begin();

The main idea, it's, first of all, create a session. Then you can do requests and after it start apple pay session.

You must declare ApplePayInstance variable above class, to trick apple pay session, so that it consider it as gesture, Also don't call in promises

http://baiduhix.blogspot.com/2018/06/must-create-new-applepaysession-from.html

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论