File: /www/wwwroot/welomall.mnbola.site/wp-content/plugins/wlstar/class-wc-wlstar.php
<?php
if (!defined('ABSPATH')) {
exit; // Exit if accessed directly
}
/**
* wlstar Payment Gateway
*
* Provides an wlstar Payment Gateway.
*
* @class WC_WlStar
* @extends WC_Payment_Gateway
* @version 1.0
*/
class WC_WlStar extends \WC_Payment_Gateway
{
var $wlstar_gateway_config;
var $current_currency;
var $multi_currency_enabled;
var $payment_method;
const XIN_VERSION = 'V5.0.1';
public function __construct()
{
$this->current_currency = get_option('woocommerce_currency');
$this->multi_currency_enabled = in_array('woocommerce-multilingual/wpml-woocommerce.php', apply_filters('active_plugins', get_option('active_plugins'))) && get_option('icl_enable_multi_currency') == 'yes';
$this->charset = strtolower(get_bloginfo('charset'));
if (!in_array($this->charset, array('gbk', 'utf-8'))) {
$this->charset = 'utf-8';
}
// WooCommerce required settings
$this->id = 'wlstar';
$this->icon = apply_filters('woocommerce_wlstar_icon', plugins_url('assets/images/logo.png', __FILE__));
$this->has_fields = true;
$this->method_title = __('WlStar', 'wlstar');
$this->order_button_text = 'Place order';
$this->notify_url = WC()->api_request_url('WC_WlStar');
// Load the settings.
$this->init_form_fields();
$this->init_settings();
// Define user set variables
$this->title = 'Credit Card';
//支付请求地址
$this->merchantId = $this->get_option('merchantId');
$this->accountId = $this->get_option('accountId');
$this->secureKey = $this->get_option('secureKey');
$this->order_prefix_enabled = $this->get_option('order_prefix_enabled');
$this->order_prefix = $this->get_option('orderPrefix');
$this->debug = $this->get_option('debug');
// Logs
if ('yes' == $this->debug) {
$this->log = new WC_Logger();
}
// Actions
add_action('woocommerce_update_options_payment_gateways', array($this, 'process_admin_options')); // WC <= 1.6.6
add_action('woocommerce_update_options_payment_gateways_' . $this->id, array($this, 'process_admin_options')); // WC >= 2.0
add_action('woocommerce_thankyou_wlstar', array($this, 'thankyou_page'));
add_action('woocommerce_receipt_wlstar', array($this, 'receipt_page'));
// Payment listener/API hook
add_action('woocommerce_api_wc_wlstar', array($this, 'notify'));
add_action('woocommerce_api_wc_wlstar_info', array($this, 'receipt_page'));
add_action('woocommerce_api_wc_wlstar_return', array($this, 'return_page'));
add_action('wp_enqueue_scripts', array($this, 'wlstar_jquery_box_scripts'));
add_action('woocommerce_api_wc_wlstar_message', array($this, 'message_page'));
add_action('woocommerce_api_wc_wlstar_query', array($this, 'queryStatus'));
}
/**
* Initialise Gateway Settings Form Fields
*
* @access public
* @return void
*/
function init_form_fields()
{
global $woocommerce;
//获取返回网址
if ($_SERVER['HTTPS'] != "on") {
$http_head = "http://" . $_SERVER['HTTP_HOST'];
} else {
$http_head = "https://" . $_SERVER['HTTP_HOST'];
}
$this->form_fields = array(
'enabled' => array(
'title' => __('Enable/Disable', 'wlstar'),
'type' => 'checkbox',
'label' => __('Enable Welomall Star Payment', 'wlstar'),
'default' => 'no'
),
'merchantId' => array(
'title' => __('Merchant Id', 'wlstar'),
'type' => 'text',
'description' => __('Please enter the merchant id.', 'wlstar'),
'default' => '',
'css' => 'width:400px'
),
'accountId' => array(
'title' => __('Account Id', 'wlstar'),
'type' => 'text',
'description' => __('Please enter the account id.', 'wlstar'),
'default' => '',
'css' => 'width:400px'
),
'secureKey' => array(
'title' => __('Security Key', 'wlstar'),
'type' => 'text',
'description' => __('Please enter the security key', 'wlstar'),
'default' => '',
'css' => 'width:400px'
),
'gateway' => array(
'title' => __('Gateway', 'wlstar'),
'type' => 'text',
'description' => __('Please enter the gateway', 'wlstar'),
'default' => 'https://testcheckout.welomall.com',
'css' => 'width:400px'
),
'orderPrefix' => array(
'title' => __('Order No prefix', 'wlstar'),
'type' => 'text',
'description' => __('Please enter the order no prefix', 'wlstar'),
'default' => 'wl-',
'css' => 'width:400px'
),
'debug' => array(
'title' => __('Debug Log', 'wlstar'),
'type' => 'checkbox',
'label' => __('Enable logging', 'wlstar'),
'default' => 'no',
'description' => __('Log WlStar events, such as trade status, inside <code>woocommerce/logs/wlstar.txt</code>', 'wlstar')
)
);
// For WC2.2+
if (function_exists('wc_get_log_file_path')) {
$this->form_fields['debug']['description'] = sprintf(__('Log WlStar events, such as trade status, inside <code>%s</code>', 'wlstar'), wc_get_log_file_path('wlstar'));
}
}
/**
* 附加到页面上的表单数据
*/
public function payment_fields()
{
include __DIR__ . "/tpl/form.php";
}
/**
* Admin Panel Options
* - Options for bits like 'title' and account etc.
*
* @since 1.0
*/
public function admin_options()
{
?>
<h3><?php _e('Welomall Star Payment', 'wlstar'); ?></h3>
<p><?php _e('Welomall Star is one of the most widely used payment method in China, customer can pay with or without an welomall star account', 'FirstTeam'); ?></p>
<table class="form-table">
<?php
// Generate the HTML For the settings form.
$this->generate_settings_html();
?>
</table>
<!--/.form-table-->
<?php
}
public function thankyou_page()
{
if ($this->instructions) {
echo wpautop(wptexturize($this->instructions));
}
}
/**
* 返回订单号(加了前缀的)
*/
private function getOrderNo($orderId)
{
return $this->order_prefix . $orderId;
}
/**
* Process the payment and return the result
* 支付处理
*
* @access public
* @param int $order_id
* @return array
*/
public function process_payment($order_id)
{
global $woocommerce;
$order = wc_get_order($order_id);
$total = $order->get_total();
$country = trim(get_post_meta($order_id, '_billing_country', true));
$currency = trim(get_post_meta($order_id, '_order_currency', true));
$notifyUrl = WC()->api_request_url('WC_WlStar'); // 异步地址
$returnUrl = WC()->api_request_url('WC_WlStar_RETURN');
//信用卡信息
$cardNo = str_replace(' ', '', $_POST['wlstarpay_card_number']);
$cardExpireMonth = trim($_POST['wlstarpay_expire_month']);
$cardExpireYear = trim($_POST['wlstarpay_expire_year']);
$cardSecurityCode = trim($_POST['wlstarpay_cvv']);
// 持卡人信息/账单信息
$firstName = trim(get_post_meta($order_id, '_billing_first_name', true));
$lastName = trim(get_post_meta($order_id, '_billing_last_name', true));
$address1 = trim(get_post_meta($order_id, '_billing_address_1', true));
$address2 = trim(get_post_meta($order_id, '_billing_address_2', true));
$city = trim(get_post_meta($order_id, '_billing_city', true));
$state = trim(get_post_meta($order_id, '_billing_state', true));
$country = trim(get_post_meta($order_id, '_billing_country', true));
$zip = trim(get_post_meta($order_id, '_billing_postcode', true));
$email = trim(get_post_meta($order_id, '_billing_email', true));
$phone = trim(get_post_meta($order_id, '_billing_phone', true));
// 发货信息
$shipFirstName = trim(get_post_meta($order_id, '_shipping_first_name', true));
$shipLastName = trim(get_post_meta($order_id, '_shipping_last_name', true));
$shipAddress1 = trim(get_post_meta($order_id, '_shipping_address_1', true));
$shipAddress2 = trim(get_post_meta($order_id, '_shipping_address_2', true));
$shipCity = trim(get_post_meta($order_id, '_shipping_city', true));
$shipState = trim(get_post_meta($order_id, '_shipping_state', true));
$shipCountry = trim(get_post_meta($order_id, '_shipping_country', true));
$shipZip = trim(get_post_meta($order_id, '_shipping_postcode', true));
$countryCode = trim(get_post_meta($order_id, '_shipping_country', true));
// 发货信息为空,自动获取账单信息
$shipFirstName = empty($shipFirstName) ? $firstName : $shipFirstName;
$shipLastName = empty($shipLastName) ? $lastName : $shipLastName;
$shipAddress1 = empty($shipAddress) ? $address1 : $shipAddress1;
$shipAddress2 = empty($shipAddress) ? $address2 : $shipAddress2;
$shipCity = empty($shipCity) ? $city : $shipCity;
$shipState = empty($shipState) ? $state : $shipState;
$shipCountry = empty($shipCountry) ? $country : $shipCountry;
$shipZip = empty($shipZip) ? $zip : $shipZip;
$countryCode = empty($countryCode) ? $country : $countryCode;
$orderNo = $this->getOrderNo($order_id);
$str = $this->merchantId . $this->accountId . $orderNo . $currency . $total . $firstName . $lastName . $cardNo . $cardExpireYear . $cardExpireMonth . $cardSecurityCode . $email . $this->secureKey;
$signInfo = strtoupper(hash('sha256', $str));
$goodsInfo = [];
foreach ($order->get_items() as $item) {
$name = $item->get_name();
$subtotal = wc_format_decimal($order->get_line_subtotal($item), 2);
$quantity = $item->get_quantity();
$goodsInfo[] = @implode('#,#', [$name, 0, round($subtotal / $quantity, 2), $quantity]);
}
$goodsInfo = @implode('#;#', $goodsInfo);
$os = $_POST['wlstarpay-os'];
$brower = $_POST['wlstarpay-brower'];
$timeZone = $_POST['wlstarpay-time_zone'];
$resolution = $_POST['wlstarpay-resolution'];
$customOrderNumber = get_post_meta($order_id, '_order_number', true); // 其他插件的自定义订单ID
$post_data = array(
'os' => $os,
'brower' => $brower,
'time_zone' => $timeZone,
'resolution' => $resolution,
'merchant_id' => $this->merchantId,
'account_id' => $this->accountId,
'order_no' => $orderNo,
'amount' => $total,
'currency' => $currency, // 三位国码
'items' => $goodsInfo,
'notifyUrL' => $notifyUrl, //can be Null
'shopper_id' => $email,
'shopper_email' => $email,
'shopper_ip' => $this->getClientIp(),
'shopper_phone' => $phone,
// Card Info
'first_name' => $firstName,
'last_name' => $lastName,
'card' => $cardNo,
'expiration_month' => $cardExpireMonth,
'expiration_year' => $cardExpireYear,
'security_code' => $cardSecurityCode,
// Cardholder Info
'billing_country' => $country,
'billing_state' => $state,
'billing_city' => $city, //can be Null
'billing_address' => $address1 . $address2,
'billing_postal_code' => $zip,
'browser_lang' => $this->getBrowserLanguage(),
'website' => empty($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_HOST'] : $_SERVER['HTTP_REFERER'],
//Shipping Info (Optional) can be Null
'delivery_firstname' => $shipFirstName,
'delivery_lastname' => $shipLastName,
'delivery_country' => $shipCountry,
'delivery_state' => $shipState,
'delivery_city' => $shipCity,
'delivery_address' => $shipAddress1 . $shipAddress2,
'delivery_postal_code' => $shipZip,
'note' => $customOrderNumber ? $customOrderNumber : $order->data['customer_note'],
'encryption_data' => $signInfo,
);
$result = $this->sendGateway($this->get_option('gateway'), $post_data);
$this->log("接收到同步网关数据:" . json_encode($result));
if (isset($result['issuer_url'])) {
return [
'result' => 'success',
'redirect' => $result['issuer_url'] . "&return_url=$returnUrl¬ify_url=$notifyUrl"
];
} else {
if ($result['order_status'] == 1) {
// 添加订单备注
if ($order->get_status() === 'pending') {
$order->add_order_note(sprintf(__('Welomall STar SaaS payment complete (Trans ID: %s)', 'wc-wlstar'), $result['transaction_id']));
$order->payment_complete($result['transaction_id']);
$woocommerce->cart->empty_cart();
}
return [
'result' => 'success',
'redirect' => $this->get_return_url($order)
];
} elseif ($result['order_status'] == -1) {
return [
'result' => 'success',
'redirect' => WC()->api_request_url('WC_WlStar_message') . '?order_id=' . $order_id
];
} else {
return [
'result' => 'error',
'error' => $result['result_info'],
];
}
}
}
/**
* Output for the order received page.
* @param array $order
* @access public
* @return void
*/
function receipt_page()
{
}
function wlstar_jquery_box_scripts()
{
wp_enqueue_style('jquery-box-style', plugins_url('/assets/css/wlstar.css', __FILE__));
}
/**
* Check for wlstar notify Response
* 异步通知
* @access public
* @return void
*/
function notify()
{
$data = $_POST;
$this->log("接收到异步通知数据:" . json_encode($data));
$signKey = $this->secureKey;
$encryptionData = strtoupper(hash('sha256', $data['merchant_id'] . $data['account_id'] . $data['transaction_id'] . $data['order_no'] . $data['currency'] . $data['amount'] . $data['order_status'] . $data['result_info'] . $signKey));
if ($encryptionData != $data['encryption_data']) {
$this->log("签名错误");
exit;
}
$rawOrderId = str_replace($this->order_prefix, '', $data['order_no']);
$order = wc_get_order($rawOrderId);
if (!$order) {
$this->log("订单不存在");
exit;
}
if ($data['order_status'] == 1) {
// 添加订单备注
if ($order->get_status() === 'pending') {
$order->add_order_note(sprintf(__('Welomall STar SaaS payment complete (Trans ID: %s)', 'wc-wlstar'), $data['transaction_id']));
$order->payment_complete($data['transaction_id']);
$this->log('支付通知处理成功');
} else {
$this->log('返回支付状态正常,处理本地订单失败:' . $order->get_status());
}
echo 'success';
exit;
}
}
/**
* 同步返回页面
*/
function return_page()
{
global $woocommerce;
$data = $_GET;
$this->log("接收到同步返回数据:" . json_encode($data));
$rawOrderId = str_replace($this->order_prefix, '', $data['order_no']);
$order = wc_get_order($rawOrderId);
$signKey = $this->secureKey;
$encryptionData = strtoupper(hash('sha256', $data['merchant_id'] . $data['account_id'] . $data['transaction_id'] . $data['order_no'] . $data['currency'] . $data['amount'] . $data['order_status'] . $data['result_info'] . $signKey));
if ($encryptionData != $data['encryption_data']) {
$this->log("同步返回数据:签名错误");
echo esc_html_e('Error Sign', 'woocommerce');
exit;
}
if ($data['order_status'] == 1) {
// 处理订单
if ($order->get_status() === 'pending') {
$order->add_order_note(sprintf(__('Welomall STar SaaS payment complete (Trans ID: %s)', 'wc-wlstar'), $data['transaction_id']));
$order->payment_complete($data['transaction_id']);
$woocommerce->cart->empty_cart();
}
header("location:" . $this->get_return_url($order));
} else {
if ($data['order_status'] == -1) {
header("location:" . WC()->api_request_url('WC_WlStar_message') . '?order_id=' . $rawOrderId);
} else {
echo esc_html_e('Unfortunately your order cannot be processed as the originating bank/merchant has declined your transaction. Please attempt your purchase again.', 'woocommerce');
echo "<a href='" . wc_get_checkout_url() . "'>buy again</a>";
exit;
}
}
}
/**
* 消息页面
*/
function message_page()
{
get_header();
$orderId = $_GET['order_id'];
$order = wc_get_order($orderId);
$assetUrl = esc_url(plugins_url('/', __FILE__)) . 'assets/images/';
$url = WC()->api_request_url('WC_WlStar_query') . '?order_id=' . $orderId;
$successUrl = $this->get_return_url($order);
$checkoutUrl = wc_get_checkout_url();
wc_get_template('message.php', array('orderId' => $orderId, 'url' => $url, 'successUrl' => $successUrl, 'assetUrl' => $assetUrl, 'checkoutUrl' => $checkoutUrl), __DIR__ . '/tpl', __DIR__ . '/tpl/');
get_footer();
exit;
}
function queryStatus()
{
$orderId = $_GET['order_id'];
$order = wc_get_order($orderId);
echo json_encode(['code' => 0, 'status' => $order->data['status']]);
exit;
}
/**
* 发送支付请求
* @param $gateway
* @param $data
* @return mixed
*/
private function sendGateway($gateway, $data)
{
$data = http_build_query($data);
$options = array(
'http' => array(
'method' => 'POST',
'header' => 'Content-type:application/x-www-form-urlencoded',
'content' => $data,
'timeout' => 15 * 60 // timeout unit: second
)
);
$context = stream_context_create($options);
$result = file_get_contents($gateway . '/v1/authorise', false, $context);
$result = simplexml_load_string($result, 'SimpleXMLElement', LIBXML_NOCDATA);
$r = json_encode($result);
return json_decode($r, true);
}
/**
* 获取客户端IP
* @return mixed|string
*/
private function getClientIp()
{
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$online_ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
$online_ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif (isset($_SERVER['HTTP_X_REAL_IP'])) {
$online_ip = $_SERVER['HTTP_X_REAL_IP'];
} else {
$online_ip = $_SERVER['REMOTE_ADDR'];
}
$ips = explode(",", $online_ip);
return $ips[0];
}
/**
* 返回浏览器语言
* @return mixed|string
*/
private function getBrowserLanguage()
{
$languages = @explode(';', $_SERVER['HTTP_ACCEPT_LANGUAGE']);
$s = @explode(',', $languages[0]);
if ($s && is_array($s)) {
return $s[0];
} else {
return 'en-US';
}
}
private function log($message)
{
if (!($this->log)) {
$this->log = new WC_Logger();
}
$this->log->add('wlstar', $message);
}
}