【问题标题】:PayPal JavaScript SDK with a PHP server?带有 PHP 服务器的 PayPal JavaScript SDK?
【发布时间】:2021-08-18 12:24:03
【问题描述】:

我是第一次使用 PayPal 标准付款,在我的“payNow”PHP 页面上使用他们 button generator 中的代码。我对 PHP 和 JavaScript 还很陌生,但精通 C#/MSSQL。 PayPal提供的代码是(加上一点PHP修改URL):

<!-- paypal start -->

<div id="smart-button-container">
      <div style="text-align: center;">
        <div style="margin-bottom: 1.25rem;">
          <p>Appster - including updates</p>
          <select id="item-options"><option value="Annual" price="360.00">Annual - 360.00 GBP</option><option value="Monthly" price="30.00">Monthly - 30.00 GBP</option></select>
          <select style="visibility: hidden" id="quantitySelect"></select>
        </div>
      <div id="paypal-button-container"></div>
      </div>
    </div>
    <?php
        $url = "https://www.paypal.com/sdk/js";
        $url .= "?client-id=" . PAYPAL_CLIENT_ID;
        $url .= "&debug=true";
        $url .= "&commit=true";
        $url .= "&currency=GBP";
        $url .= "&locale=en_GB";
        echo '<script src="' . $url . '" data-sdk-integration-source="button-factory"></script>' . PHP_EOL;
    ?>
    <!-- <script src="https://www.paypal.com/sdk/js?client-id=sb&enable-funding=venmo&currency=GBP" data-sdk-integration-source="button-factory"></script> -->
    <script>
        function initPayPalButton() {
            var shipping = 0;
            var itemOptions = document.querySelector("#smart-button-container #item-options");
            var quantity = parseInt();
            var quantitySelect = document.querySelector("#smart-button-container #quantitySelect");
            
            if (!isNaN(quantity)) {
                quantitySelect.style.visibility = "visible";
            }
            
            var orderDescription = 'Appster - including upgrades';
            if(orderDescription === '') {
                orderDescription = 'Item';
            }
            
    paypal.Buttons({
      style: {
        shape: 'rect',
        color: 'gold',
        layout: 'vertical',
        label: 'paypal',
        
      },
      createOrder:
      function(data, actions) {
        var selectedItemDescription = itemOptions.options[itemOptions.selectedIndex].value;
        var selectedItemPrice = parseFloat(itemOptions.options[itemOptions.selectedIndex].getAttribute("price"));
        var tax = (20 === 0 || false) ? 0 : (selectedItemPrice * (parseFloat(20)/100));
        if(quantitySelect.options.length > 0) {
          quantity = parseInt(quantitySelect.options[quantitySelect.selectedIndex].value);
        } else {
          quantity = 1;
        }

        tax *= quantity;
        tax = Math.round(tax * 100) / 100;
        var priceTotal = quantity * selectedItemPrice + parseFloat(shipping) + tax;
        priceTotal = Math.round(priceTotal * 100) / 100;
        var itemTotalValue = Math.round((selectedItemPrice * quantity) * 100) / 100;

        return actions.order.create({
          purchase_units: [{
            description: orderDescription,
            amount: {
              currency_code: 'GBP',
              value: priceTotal,
              breakdown: {
                item_total: {
                  currency_code: 'GBP',
                  value: itemTotalValue,
                },
                shipping: {
                  currency_code: 'GBP',
                  value: shipping,
                },
                tax_total: {
                  currency_code: 'GBP',
                  value: tax,
                }
              }
            },
            items: [{
              name: selectedItemDescription,
              unit_amount: {
                currency_code: 'GBP',
                value: selectedItemPrice,
              },
              quantity: quantity
            }]
          }]
        });
      },
    onApprove:
        function(data, actions)
        {
            return actions.order.capture().then
            (
                function(orderData)
                {
                    // Full available details
                    console.log('Capture result', orderData, JSON.stringify(orderData, null, 2));

                    // 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');
                    actions.redirect('paymentReceived.php');
                    //var successfulPurchase = document.getElementById('successfulPurchase');
                    //successfulPurchase.style.display = 'table-row';
                }
            );
        },
    onError: 
        function(err)
        {
            alert("Payment Failed");
            console.log(err);
        },
    }).render('#paypal-button-container');
  }
  initPayPalButton();
    </script>
    
<!-- paypal end -->

成功付款后,我想使用 JavaScript 来使用另一个 PHP 页面(尚未编写)来更新我的后端数据库,即用户已经购买了一些东西,方法是向表中写入一行。我的猜测是,正确的做法是编写一个 RESTful API 页面来写入数据,使用 POST 函数。我的问题是,我是否在redirect 语句之前的onApprove 函数中调用它? API 失败时会发生什么?您建议如何处理?

【问题讨论】:

  • 如果出现任何问题,MySQL 将返回错误,您可以将代码设计为在发生这种情况时不执行任何操作,但会出错并要求他们重试。因此,如果发生这种情况,您不应该做任何无法撤消的重大事情......
  • 至于付款,它是通过 API 完成的,所以是的,需要一些 REST。然而,你想如何设置它取决于你,但大多数保持简单。您向贝宝发送它需要知道的信息,它会告诉您请求是否已被批准或拒绝。如果有一个错误说paypal无法连接,你会得到一个404错误或者你有时间重新检查的东西......至于存储这些数据,你什么都不做,直到它被批准100%;如果您需要为该项目提供服务,那么您的工作就是在您的终端跟踪它以进行进一步处理/等。
  • 感谢@blanknamefornow(顺便说一句,这个名字很棒)。我对这些东西很陌生,所以请检查我打算做的事情是否正确。

标签: php paypal


【解决方案1】:

不要使用actions.order.create() / .capture() 在客户端创建和捕获订单,然后再将信息发送到服务器。更改为适当的服务器端集成。

按照Set up standard payments 指南在您的服务器上创建两条路线,一条用于“创建订单”,一条用于“捕获订单”documented here。两个路由都应该只返回 JSON 数据(没有 HTML 或文本)。在第二条路线中,当捕获 API 成功时,您应该将其生成的付款详细信息存储在您的数据库中(特别是 purchase_units[0].payments.captures[0].id,这是 PayPal 交易 ID)并执行任何必要的业务逻辑(例如发送确认电子邮件或预订产品)立即将您的返回 JSON 转发给前端调用者。

  • 关于只返回 JSON 数据的这一点很重要,因为草率的 php 代码可能会输出其他内容,或者您​​可能正在使用具有额外打印语句的 Checkout-PHP-SDK 示例代码。删除类似的东西,只输出 JSON!您可以在浏览器的“网络”标签中查看响应正文。

将您的 2 条路由与前端审批流程配对:https://developer.paypal.com/demo/checkout/#/pattern/server

【讨论】:

    猜你喜欢
    • 2021-03-22
    • 2023-02-07
    • 2019-07-29
    • 2013-08-24
    • 2015-06-06
    • 2018-04-29
    • 2022-01-08
    • 1970-01-01
    • 2019-03-26
    相关资源
    最近更新 更多