Day22 - 铁人付外挂实作付款类别(ㄧ)- WooCommerce 金流介绍

WooCommerce 的金流主要分为两种,即时与非即时完成付款,即时指的是当订单成立後就可以取得消费者的付款结果,像是信用卡、WebATM,WooCommerce 提供三种模式来处理即时付款:

  1. 付款表单 - 让消费者直接在站内完成信用卡或是付款相关资讯的填写,由於安全性的考量,台湾有支援这种模式的金流商相对较少,但因为其结帐的便利性可降低付款跳出率,这几年有不少厂商开始支援 Token 交易代码化,也就是传送过程中并非直接传送消费者的卡号,而是使用一串代码来避免直接暴露。

  2. Iframe 嵌入 - 按下结帐时使用 Iframe 显示卡号输入画面,之前国内也有金流商是采用这种方式付款,但该金流商目前已停止该类型的付款方式。

  3. 页面跳转 - 不让消费者在站内提供付款资讯,而是跳转到金流商的页面进行付款,这是目前的主流方式,根据金流商运作模式,有些是使用 Form 来 Post,或是需要呼叫 API 来取得跳转网址。

非即时付款的金流常见的有虚拟转帐帐号、超商代码缴费,有些金流商会需要跳转到他们的介面,像是选择要产生的转帐帐号是用哪家银行、列印哪家超商的缴费代码,也有厂商没提供这些选择,就是单纯的直接回传固定一家银行或超商的缴费资讯,这种类型的就是直接将回传结果显示在站内即可。

WooCommerce 最常见的结帐流程为:加入购物车 > 输入帐单资讯 > 跳转到第三方付款页 > 跳转回站内感谢页,接下来说明新增 WooCommerce 金流付款的架构。

WooCommerce 新增金流 Gateway

在实作之前我们先厘清中英对照,Payment 指的是付款公司,实务上会是把金流商的公司名称作为 Payment,而一个金流商会提供许多不同的付款方式,像是信用卡、ATM、超商代码等等,而这些付款方式就是 Gateway。

首先继承 WooCommerce 的金流类别 WC_Payment_Gateway,并将类别的宣告放在 plugins_loaded 勾点里面:

function add_gateway() {
    class CreditCard_Gateway extends WC_Payment_Gateway {}
}
add_action( 'plugins_loaded', 'add_gateway' );

CreditCard_Gateway不用建立实例,这部分 WooCommerce 会帮我们处理,在命名上最好可以很直观的理解这是哪一种付款方式,接下来在 woocommerce_payment_gateways 勾点新增付款方式的类别名称即可:

function add_gateway_class( $methods ) {
    $methods[] = 'CreditCard_Gateway'; 
    return $methods;
}

add_filter( 'woocommerce_payment_gateways', 'add_gateway_class' );

这样就能完成金流功能的注册,接下来我们需要实作 My_Gateway 类别。

CreditCard_Gateway 类别必要实作属性与方法

首先要有建构式来指定金流名称、ID、描述等等基本资料,另外还需要执行设定项的初始化:

function add_gateway() {
	class CreditCard_Gateway extends WC_Payment_Gateway {
		public function __construct() {
			$this->id                 = 'my_credit_card';
			$this->icon               = 'imgUrl';
			$this->has_fields         = false;
			$this->method_title       = '信用卡';
			$this->method_description = '使用信用卡付款';
		}
	}
}
add_action( 'plugins_loaded', 'add_gateway' );

$this->id – 付款方式的唯一 ID,最好带有自己的前缀,因为同一间金流商可能会有其他第三方开发金流外挂,如果只用金流商的前缀发生冲突的机率很高

$this->icon – 显示在前台结帐页付款名称旁的图标,让消费者知道他们会透过哪一间金流公司进行付款

$this->has_fields – 在结帐页是否有提供付款资讯填写表单,因为我们大部分都是使用跳转到第三方,所以这边设成 false 即可

$this->method_title – 付款方式名称,会显示在 WooCommerce 的设定页

$this->method_description - 付款方式描述,会显示在 WooCommerce 的设定页

设定完属性後,建构式里面还需要设定以下内容:

function add_gateway() {
	class CreditCard_Gateway extends WC_Payment_Gateway {
		public function __construct() {
			// 略
			$this->init_form_fields();
			$this->init_settings();
			
			$this->title = $this->get_option( 'title' );
			$this->description = $this->get_option( 'description' );

			add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) );
		}
	}
}
add_action( 'plugins_loaded', 'add_gateway' );

第一个方法 init_form_fields() 稍後会实作,它的功用在建立 Gateway 的设定项,在前面的文章中,我们已经把金流的相关设定放在全域设定里面,因为一个金流商会提供多种 Gateway,所以把设定放在 Gateway 里面的话对於使用者来说会很麻烦,一样的金流商店代号、密钥资讯在信用卡、ATM、超商代码都要个别输入,因此这类资讯放在全域设定里面会比较恰当。

但如果你接的金流只有一个 Gateway 的话,把设定项放在这边就很适合。第二个方法是 init_settings(),它的功用是初始化设定,之後就可以透过 get_option() 取得 init_form_fields 里面的设定栏位值,像是:

$this->title = $this->get_option( 'title' );
$this->description = $this->get_option( 'description' );

title 跟 description 稍後会实作在 init_form_field() 方法里面,而这边 $this->title 以及 $this->description 有别於 method_titlemethod_description,他们是显示在前台结帐页的付款方式名称,这个名称可以透过设定项来让使用者自行修改,而最後的勾点 woocommerce_update_options_payment_gateways_{gateway_id} 则是更新设定内容,process_admin_options 我们不需实作,交由 WC_Payment_Gateway 处理即可。

接下来是实作 init_form_fields 方法,我们只需要最基本的三个栏位即可:

function add_gateway() {
	class CreditCard_Gateway extends WC_Payment_Gateway {
		public function __construct() {
			// 略
		}
		public function init_form_fields() {
			$this->form_fields = array(
				'enabled'     => array(
					'title'   => '启用/停用',
					'label'   => '启用付款',
					'type'    => 'checkbox',
					'default' => 'no',
				),
				'title'       => array(
					'title' => '付款方式名称',
					'type'  => 'text',
				),
				'description' => array(
					'title' => '付款方式描述',
					'type'  => 'textarea',
				),
			);
		}
	}
}
add_action( 'plugins_loaded', 'add_gateway' );

最後是 process_payment 方法,它会处理点击结帐按钮後的行为,包含建立订单、改变订单状态、清空购物车、将栏位传送到金流商、取得网址後进行页面跳转,这部分我们会在下一篇串接信用卡来进行实作。

WC API 的用途

通常传送订单资料给金流商的时候,都会需要带一个成功付款後的完成结帐网址,当金流商走完流程後就会根据该网址来进行页面跳转,WooCommerce API 提供一个动态的勾点 woocommerce_api_{slug},只要替换 slug 就能制造出这个跳转网址,范例如下:

function redirect_thankyou_page( $order ){
	// 处理金流商回传的参数
	$args = $_REQUEST;
	wp_safe_redirect( $order->get_checkout_order_received_url() );
}
add_action( 'woocommerce_api_thankyou', array( $this, 'redirect_thankyou_page' ) );

当金流商导回 https://example.com/wc-api/thankyou 的时候,我们就能拿到参数的资讯做处理,然後将页面跳转到感谢页,在非即时付款金流商要背景通知付款完成的情境下,也可以使用这个勾点来做到接收参数的功能。

以下为付款方式 Gateway 类别的完整基础架构:

function add_gateway() {
	class CreditCard_Gateway extends WC_Payment_Gateway {

		public function __construct() {
			$this->id                 = 'credit_card';
			$this->icon               = 'imgUrl';
			$this->has_fields         = false;
			$this->method_title       = '信用卡';
			$this->method_description = '使用信用卡付款';

			$this->init_form_fields();
			$this->init_settings();

			$this->title       = $this->get_option( 'title' );
			$this->description = $this->get_option( 'description' );

			add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) );
		}

		public function init_form_fields() {
			$this->form_fields = array(
				'enabled'     => array(
					'title'   => '启用/停用',
					'label'   => '启用付款',
					'type'    => 'checkbox',
					'default' => 'no',
				),
				'title'       => array(
					'title' => '付款方式名称',
					'type'  => 'text',
				),
				'description' => array(
					'title' => '付款方式描述',
					'type'  => 'textarea',
				),
			);
		}

		public function process_payment(){
			// 处理点击结帐按钮後的行为
		}
	}
}
add_action( 'plugins_loaded', 'add_gateway' );

下一篇我们来实作铁人付金流的信用卡 Gateway。

本文同步发表於:https://oberonlai.blog/tw/woocommerce-payment-gateway/


<<:  day7 我不要了,这不是肯德基 cancel

>>:  Swift 语言和你 SAY HELLO!!

从 JavaScript 角度学 Python(27) - 传值?传参考?

前言 已经快到铁人赛的结尾了,但是我现在才想到我好像少讲了一个东西,就是关於传值与传参考的部分,所以...

离职倒数18天:重新开始思考一个科技业大家爱揶揄的话题「PM 到底在干嘛」

我最近在考虑要找人来帮忙管理我们的 App。请认识的人介绍时,我说工作内容包括:看用户的反馈然後分类...

Laravel 技术笔记 (一)【Routing 路由】

序言 此系列文章将不定期更新,献给未来健忘的自己,也献给刚接触 Laravel 的初学者们,若您在观...

图的走访 - BFS 篇

4 图的走访 - BFS 篇 如果要好好地探索一张图,最经典的方法莫过於深度优先搜索(Depth F...

视觉化当日趋势图(3)-取得python api方法

今天我们要来撰写取得python api资料的方法, 首先先打开ShioajiServiceImpl...