首页 文章

Angularjs Laravel Stripe集成 - 响应服务器和其他细节缺失

提问于
浏览
0

我已经设置了Angular Storefront应用程序 . 我有一个购物车功能和条纹“支付卡”按钮等几乎看起来像这样:

<form action="/#/order" method="POST">

        <script
          src="https://checkout.stripe.com/checkout.js" class="stripe-button"
          data-key="{{ stripeApiKey }}"
          data-billingAddress=true
          data-shippingAddres=true
          data-amount="{{ amount }}"
          data-name="StoreFront Name"
          data-description="Custom-Made Jewellery"
          data-image="../images/www/logo.png"
          data-locale="auto">
        </script>
      </form>

到目前为止,Evrything工作得很好 . 我提交表单并且条带返回令牌,但表单按照路径 localhost/order (没有#符号)而不是angular的 localhost/#/order 进入服务器 .

  • 为什么条带强制重定向?换句话说,为什么没有角度捕获这个回叫?

无论如何 . 然后我用Laravel创建一个路由来捕获它并转储以检查返回的数据,如下所示:

Route::post('/order', function($request){ dd($request); });

是的,除了金额丢失之外,还会返回由条带生成的表单捕获的数据...我的意思是包括stripeToken在内的所有内容,买家的详细信息如:姓名,电子邮件,结算和送货地址都会被退回但有关金额的详细信息缺失 .

  • 这是正常的还是我错过了什么?

  • 最后货币仍显示默认值:我在哪里可以将货币从美元兑换成英镑?

提前致谢

3 回答

  • 0

    1 /我不认为Checkout强制重定向,但我不太了解Angular解释发生了什么,抱歉 .

    2 /是的,这是正常的 . 传递给 data-amount configuration option中的Checkout的金额仅用于显示目的 . 实际收取的金额是您在服务器端代码的charge creation request中的 amount 参数中传递的金额 .

    如果您需要用户指定的金额(例如,如果您需要将金额添加到表单中 . 这是一个简单的JSFiddle来说明这种情况:https://jsfiddle.net/ywain/g2ufa8xr/

    3 /您可以使用 data-currency 参数更改Checkout表单中显示的货币 . 就像 data-amount 一样,这仅用于显示目的,用于收费的实际货币由费用创建中的 currency 参数指定 .

  • 0

    除了阻止表单提交事件和停止事件传播的默认操作外,Stripe不会涉及您的表单 . 结帐过程完成后,它会将相关数据附加到您的表单,然后触发由HTML / Javascript本地处理的表单提交事件 .

    我建议使用像https://github.com/tobyn/angular-stripe-checkout之类的东西来让Angular正确处理你的Stripe响应 .

    否则,您可以在表单中添加ng-submit =“handleStripeCheckout($ event)”而不是action =“/#/ form” . 当Stripe的结帐过程完成时,将运行$ scope.handleStripeCheckout方法,您可以分析该方法中的新表单数据 .

    编辑:Stripe checkout.js实际上触发了form.submit() . 考虑到几乎没有浏览器正确处理这个问题,这是一个非常糟糕的错误 . (使用提交()从链接提交的表单不能被onsubmit处理程序捕获)

  • 1

    这就是我设法做到的 .

    我采用 custom form 方法 . 我有一个表单模板来捕获 billing.template.html 中的客户和卡输入,如下所示:

    <form method="POST" id="payment-form">
      <span class="payment-errors"></span>
    
      <div>
        <label>Name</label>
        <input type="text" name="name" data-stripe="name">
      </div>
    
      <div>
        <label>Email</label>
        <input type="text" name="email" data-stripe="address_email">
      </div>
    
      <div>
        <label>Address Line 1</label>
        <input type="text" name="street" data-stripe="address_line1">
      </div>
    
      <div>
        <label>Postcode</label>
        <input type="text" name="postcode" data-stripe="address_zip">
      </div>
    
      <div>
        <label for="country">Country</label>
          <select ng-include="'../templates/_partials/_countrylist.html'"
            id="countries" name="country" class="form-control"
            name="country" ng-model="country" id="country" size="2"
            data-stripe="address_country" required></select>
      </div>
    
      <div class="form-row">
        <label>
          <span>Card Number</span>
          <input type="text" name="cardNumber" size="20" data-stripe="number"/>
        </label>
      </div>
    
      <div class="form-row">
        <label>
          <span>CVC</span>
          <input type="text" name="cvc" size="4" data-stripe="cvc"/>
        </label>
      </div>
    
      <div class="form-row">
        <label>
          <span>Expiration (MM/YYYY)</span>
          <input type="text" name="expMonth" size="2" data-stripe="exp-month"/>
        </label>
        <span> / </span>
        <input type="text" name="expYear" size="4" data-stripe="exp-year"/>
      </div>
    
      <button id="customButton">Pay with Card</button>
    </form>
    

    我知道我们不应该在那些表单输入中使用 name 属性但我离开它们所以我可以使用角度验证,但我在提交到服务器之前使用jquery删除它们 .

    现在我创建了一个控制器来处理表单: BillingController.js . 在那里我有一个"on click"处理程序,通过获取表单并做一些准备工作来启动事情:禁用按钮以防止进一步点击并删除那些'dreaded'名称属性,纪念:

    $('#customButton').on('click',function(event) {
        var $form = $('#payment-form');
    
        // Disable the submit button to prevent repeated clicks
        $form.find('button').prop('disabled', true);
    
        //NOW REMOVE THOSE NAME ATTRIBUTES
        $form.find('input').removeAttr('name');
    
        // call Stripe object and send form data to get back the token.
        // NOTE first argument is $form 
        Stripe.card.createToken($form, stripeResponseHandler);
    
        // Prevent the form from submitting with the default action
        return false;
      });
    

    现在让我引用这里的文档,因为这是非常重要的理解: https://stripe.com/docs/tutorials/forms

    需要注意的重要代码是对Stripe.card.createToken的调用 . 第一个参数是包含用户输入的信用卡数据的表单元素 . 使用表单中指定的data-stripe属性从相关输入中获取相关值 .

    接下来我们创建 stripeResponseHandler() . 记住它是上面 Stripe.card.createToken($form, stripeResponseHandler); 中的第二个参数,当Stripe返回令牌时会调用它 .

    function stripeResponseHandler(status, response) {
      var $form = $('#payment-form');
    
      if (response.error) {
        // Show the errors on the form
        $form.find('.payment-errors').text(response.error.message);
        $form.find('button').prop('disabled', false);
      } else {
        // response contains id and card, which contains additional card details
        var token = response.id;
        // Insert the token into the form so it gets submitted to the server
        $form.append($('<input type="hidden" name="stripeToken" />').val(token));
        // and submit
        $form.get(0).submit();
      }
    };
    

    这是条纹自己的文档中的复制和粘贴内容: https://stripe.com/docs/tutorials/forms . 现在,我想说,这就是我们很多人都在嘲笑表单执行重定向等事实 - 请注意最后一行 $form.get(0).submit(); . 这是什么导致自动提交,重定向到形式上的动作,如果你有任何(在我的情况下 action 属性是没有必要的,因为我在我的控制器中进行重定向) .

    所以我决定删除 $form.get(0).submit() 并在我完成向服务器发送数据后实现自己的重定向 .

    注意:条纹的响应将包含来自 $form 的数据 - 尝试 console.log(response); 以了解要回发的内容 .

    最后:我们检查是否有任何错误返回,如果是,则显示它们 . 否则一切都好,将数据发送到服务器 .

    最终代码如下:

    function stripeResponseHandler(status, response) {
    
          var $form = $('payment-form');
    
          if (response.error) {
            // Show the errors on the form
            $form.find('.payment-errors').text(response.error.message);
          } else {
            // response contains id and card, which contains additional card details
            var token = response.id;
    
            // prepare data
            var data = {
                stripeToken: token,
                fullName: response.card.name,
                street: response.card.address_line1,
                postcode: response.card.address_zip,
                town: response.card.address_city,
                country: response.card.address_country,
                last4: response.card.last4
            };
    
            // send to server
            $http.post('/checkout', data).then(function(result){
              // here you can redirect yourself.
              window.location.href = "/#/order-complete";
            });
    
          }
        };
    

    Angular在这里非常适合条纹 . 看看这个链接: https://gist.github.com/boucher/1750368 - 从中学到很多东西 .

    我希望它能帮到今天的某个人 . 快乐的编码!

相关问题