返回

WooCommerce 结账页集成 JS SDK 支付 API 教程

javascript

WooCommerce 结账页集成 JavaScript SDK 支付 API

如何在 WordPress WooCommerce 网站的结账页面集成 JavaScript SDK 支付 API?这个问题在电商开发中相当常见。原因往往是现有插件功能不全,或者需要更灵活的支付流程定制。接下来将讨论问题、剖析原因,并提供多个解决方案。

理解问题

支付网关服务商提供的 WordPress 插件,可能只包含基本支付功能,无法完全满足所有商户需求。为了进行更高级的操作,比如管理卡片信息,使用动态支付链接,我们经常需要直接使用服务商提供的 JavaScript SDK(这里是 directpay-ipg-js)。

问题核心:提供的 SDK 需要在结账页面调用,处理交易;但插件没有提供直接配置和使用这些 SDK 功能的 GUI。 即使拥有 API 密钥、商户 ID 等必要数据,商户也不太清楚如何接入使用。这确实会让技术基础薄弱的用户感到困惑。

解决方案一:自定义代码集成

最直接的办法是直接在 WordPress 主题中加入 JavaScript 代码。 这种方法更灵活,可以控制 SDK 的各个方面。

  1. 获取 API 信息 : 首先,从支付服务商门户获取商户ID、API 密钥、商户密钥、确认回调端点、私钥,以及公钥(服务端和客户端)。将这些数据安全地保存起来,在稍后步骤会用到。

  2. 引入 SDK : 在你主题的 functions.php 文件中添加以下代码来引入 directpay-ipg-js SDK。 你也可以直接将 SDK 下载到主题目录中,然后在下面使用 <script src=""> 标签引入,如下示例中使用 npm 安装并以 import 的形式引入:

function enqueue_payment_scripts() {
    if (is_checkout()) {
         wp_enqueue_script('directpay-sdk', 'path-to-directpay/dist/index.js', array(), '1.0.0', true);
        wp_enqueue_script('custom-payment-script', get_stylesheet_directory_uri() . '/js/custom-payment.js', array('directpay-sdk'), '1.0.0', true);
        wp_localize_script('custom-payment-script', 'payment_vars', array(
            'merchant_id' => 'YOUR_MERCHANT_ID',
            'api_key' => 'YOUR_API_KEY',
            'confirmation_endpoint' => 'YOUR_CONFIRMATION_ENDPOINT',
           // ... add other needed variables
        ));
    }
}

add_action('wp_enqueue_scripts', 'enqueue_payment_scripts');

这里:

  • wp_enqueue_script 加载SDK和自定义脚本文件。
  • wp_localize_script 传递 API 密钥等敏感信息到 JavaScript 文件中。将 'path-to-directpay/dist/index.js' 替换成 SDK 在你主题中正确位置, 将 'YOUR_MERCHANT_ID' 等替换成你的实际信息.
  1. 编写自定义 JavaScript : 在主题的 js 文件夹中创建一个 custom-payment.js 文件。以下示例代码演示如何使用 directpay-ipg-js SDK 接收支付:
(function($) {
      $(document).ready(function(){
      	// 使用 wp_localize_script 函数传递的 payment_vars 数据
      	var merchantId = payment_vars.merchant_id;
          var apiKey = payment_vars.api_key;
          var confirmationEndpoint = payment_vars.confirmation_endpoint;

  		// SDK 初始化配置示例
          const directPay = DirectPayIPG(merchantId, apiKey);
          //绑定事件在submit时调用API, 此处的 $("#place_order") 根据实际的订单按钮id来替换
          $("#place_order").on("click",function (event) {
            // 阻止默认的submit事件, 我们需要自己提交表单
              event.preventDefault()

          	   let amount =  $('input[name="order_total_amount"]').val(); // get total amount from hidden input field
  			       directPay.paymentLinkV1({
  				            amount: parseInt(amount * 100),
                              confirmUrl: confirmationEndpoint,
  						   	onSuccess: function (response) {
                                // 将响应保存到hidden input field,以便后端接受,比如下面这句将 token 放在 name 为 directPayToken 的input中。 你也可以将整个 response 以 json 的形式保存起来。
                                    $('input[name="directPayToken"]').val(response.token)
  							    $('#order_review').submit(); // 继续提交表单
  							    
  	    			},
         				  onError:function(error){
  				            console.log(error)
        			         alert(JSON.stringify(error));
  	            	    }
             		 })
          })
     })

})(jQuery);

这里:

  • 导入从 wp_localize_script 传过来的API 密钥等数据
  • 获取支付金额 $('input[name="order_total_amount"]').val(), 这个需要根据你的实际情况进行修改。 如果你在购物车没有价格,需要在js/custom-payment.js 加载前设置。例如你可以在checkout html页面插入类似以下结构的数据 <input type="hidden" name="order_total_amount" value="{{order_amount}}" />,其中的 {{order_amount}} 是动态变量。你需要使用WooCommerce的一些模版变量来得到当前的订单价格.
  • 初始化 SDK.
  • 监听用户提交表单操作, 并触发 directPay.paymentLinkV1,创建支付链接,并在支付成功后提交表单
  • 请注意, confirmUrl (confirmationEndpoint)需要跟你在服务商门户设置的回调地址 保持一致。 你需要修改为实际回调地址。
  • 在前端获取到的token等参数会被提交到服务端, 你需要在服务端使用私钥(请确保私钥仅在服务端使用)再次进行验证来保证数据安全。这个属于服务端的流程了。不在前端讨论范围。
  1. 服务端验证 : 最后需要在 functions.php 里监听支付提交后的信息:
  add_action('woocommerce_checkout_create_order', 'custom_payment_server_validate');
  function custom_payment_server_validate($order) {
  	$directPayToken = $_POST['directPayToken'];

    //Use service provider server side function with Private key here for the security to validate the request, you may use CURL

     //check from service provide with merchant private key and other details
   	$validationResult =  validatePaymentRequest($directPayToken); // 这个需要使用你自己实现的逻辑
   if (!$validationResult) {
      	$order->update_status('failed', 'Payment could not be verified, please try again'); // set order to failed state
      }

   }

注意,这里的 validatePaymentRequest 需要替换成实际的服务器端验证代码, 最好用cURL发起 POST 请求与网关服务端接口进行通信,你需要服务端私钥等敏感数据。不要直接调用 SDK 做这个。服务端安全验证是不可少的步骤,这是至关重要的

  1. 其他安全建议:

    • 请勿直接将密钥等敏感信息暴露在 JavaScript 代码中。
    • 后端验证需要绝对严格,以免造成财产损失。
    • 使用HTTPS以防止网络拦截,传输加密数据
    • 确保在js/custom-payment.js文件中没有任何错误和问题,任何错误都会让用户支付失败

解决方案二:插件开发或扩展

如果你不喜欢直接修改主题文件,可以考虑开发自定义插件。插件方式结构清晰,方便维护,且在切换主题时不影响插件的功能。 插件的整体逻辑和“解决方案一”大体一致,主要区别在于如何加载 JS SDK 代码、定义参数等。

  1. 创建插件目录和文件: 在 WordPress 插件目录 wp-content/plugins/ 下创建一个名为 custom-payment-gateway 的文件夹。然后在该文件夹下创建主插件文件 custom-payment-gateway.php

  2. 编写插件头信息:custom-payment-gateway.php 中写入以下信息:

```php
<?php
/**
 * Plugin Name: Custom Payment Gateway
 * Description: Integrates a custom payment gateway with WooCommerce.
 * Version: 1.0.0
 * Author: Your Name
 */
// ... rest of code will go here ...
```
  1. 编写插件核心逻辑 :在插件中复制解决方案一中的 enqueue_payment_scripts 代码,并在functions.php使用对应的钩子woocommerce_checkout_create_order, 创建验证回调. js逻辑和前面的也保持一致. 这里就不再详细

插件架构的主要优势是可以将与支付相关的代码隔离在一个插件目录中,减少与其他代码的冲突。 如果对 WordPress 插件架构不熟悉,推荐使用此种方式。

总结

整合支付网关的 JavaScript SDK 并非难题。在了解基本原理后,采用任一种方案都是可行的。关键点在于:

  • 安全性 : 严格保护敏感数据。切记,永远不在前端暴露密钥。
  • 后端验证 : 务必在服务端进行安全校验,避免造成财产损失
  • 灵活性 :根据实际需要选择最适合你的方案。直接修改主题文件比较快捷;开发插件更规范;具体采取哪个根据自己实际情况考虑即可。

希望通过以上这些内容能帮助你更好地解决实际问题。记住安全和后端校验的重要性,并根据自己的项目需要选择合适的实施方案。