| Server IP : 43.141.49.92 / Your IP : 113.219.202.173 Web Server : Apache System : Linux VM-8-5-opencloudos 6.6.34-9.oc9.x86_64 #1 SMP PREEMPT_DYNAMIC Wed Jun 19 19:35:45 CST 2024 x86_64 User : www ( 1000) PHP Version : 8.1.27 Disable Function : passthru,exec,system,putenv,chroot,chgrp,chown,shell_exec,popen,proc_open,pcntl_exec,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,popepassthru,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,imap_open,apache_setenv MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /www/wwwroot/www.ucppt.com/wp-content/plugins/wpcom-member-pro/payment/ |
Upload File : |
<?php
namespace WPCOM\Member\Payments;
use WPCOM\Member\Order;
defined('ABSPATH') || exit;
class Wxpay_Xunhu extends Payment {
protected $_config;
protected $is_rest = false;
public function __construct() {
$this->id = 'wxpay-xunhu';
$this->title = '微信支付';
$this->icon = WPCOM_MP_URI . 'payment/wxpay/wxpay.svg';
$this->color = '#2bae67';
$this->modal = !$this->is_mobile(); // 非手机端的时候使用弹框,二维码支付
$this->_config = array();
$type = isset($_SERVER['AppType']) ? $_SERVER['AppType'] : (isset($_SERVER['HTTP_APPTYPE']) ? $_SERVER['HTTP_APPTYPE'] : '');
if($type === 'weapp' && function_exists('WWA_is_rest') && WWA_is_rest()){
$this->is_rest = true;
}
add_action('wp_ajax_WPCOM_'.$this->id.'_order_status', array($this, 'order_status'));
add_action('wp_ajax_nopriv_WPCOM_'.$this->id.'_order_status', array($this, 'order_status'));
parent::__construct();
}
public function init($index){
$appid = wpcom_mp_options('wxpay_appid');
$secret = wpcom_mp_options('wxpay_secret');
$tranasction_url = wpcom_mp_options('pay_tranasction_url');
$this->_config = array(
'appid' => $appid && isset($appid[$index]) ? trim($appid[$index]) : '',
'secret' => $secret && isset($secret[$index]) ? trim($secret[$index]) : '',
'tranasction_url' => $tranasction_url && isset($tranasction_url[$index]) && $tranasction_url[$index] ? trim($tranasction_url[$index]) : 'https://api.xunhupay.com/payment/do.html',
);
}
public function receipt_page($order_id) {
$order = Order::get_order($order_id);
if (!$order || $order->status === 'paid') return;
if($this->is_rest && preg_match('/wxpay/i', $this->id)){
$data = $this->get_pay_data($order);
// 支付网关为:https://api.xunhupay.com 跳转小程序APPID:wx2574b5c5ee8da56b,其他支付网关跳转小程序APPID:wx402faa5bd5eda155
$appid = preg_match('/\/\/api\.xunhupay\.com/i', $this->_config['tranasction_url']) ? 'wx2574b5c5ee8da56b' : 'wx402faa5bd5eda155';
$res = array(
'result' => 0,
'order_id' => $order_id,
'appid' => $appid,
'data' => $data
);
wp_send_json($res);
}else if(!$this->is_mobile()) {
$result = $this->post_payment_api($order);
if (is_wp_error($result)) { ?>
<div class="text-center" style="margin-bottom: 30px;color:#f66;">
<span style="color:red;"><?php echo $result->get_error_message(); ?></span>
</div>
<?php } else if($result && isset($result['url_qrcode'])){ ?>
<div class="wpcom-wxpay-inner">
<div id="j-wpcom-xhpay" class="wpcom-wxpay-img" data-type="<?php echo esc_attr($this->id);?>" data-order="<?php echo $order_id; ?>">
<img src="<?php echo esc_url($result['url_qrcode']);?>" style="width:240px;height:240px;">
</div>
<p class="wpcom-wxpay-note" style="line-height:2;font-size: 16px;color: #333;">使用<?php echo preg_match('/wxpay/i', $this->id) ? '微信' : '支付宝';?>扫描二维码进行支付</p>
</div>
<script src="<?php echo includes_url('js/jquery/jquery.min.js'); ?>"></script>
<script src="<?php echo WPCOM_MP_URI . 'js/pay.js'; ?>"></script>
<script> _ajax_url = "<?php echo admin_url( 'admin-ajax.php');?>"; _nonce = "<?php echo wp_create_nonce('wpcom_'.$this->id.'_receipt_page');?>"; </script>
<?php }
}
}
public function order_status() {
$order_id = isset($_POST['order_id']) && $_POST['order_id'] ? $_POST['order_id'] : '';
$nonce = isset($_POST['nonce']) && $_POST['nonce'] ? $_POST['nonce'] : '';
if($nonce && wp_verify_nonce($nonce, 'wpcom_'.$this->id.'_receipt_page')){
$order = $order_id ? Order::get_order($order_id) : '';
$user_id = get_current_user_id();
if ($order && isset($order->ID) && (!$order->user || ((int) $order->user === $user_id)) && $order->status === 'paid') {
$res = array(
'redirect' => Order::get_checkout_return_url($order->ID, $this->id),
'status' => 'paid'
);
wp_send_json($res);
}
}
}
public static function getNonceStr($length = 32){
$chars = "abcdefghijklmnopqrstuvwxyz0123456789";
$str ="";
for ( $i = 0; $i < $length; $i++ ) {
$str .= substr($chars, mt_rand(0, strlen($chars)-1), 1);
}
return $str;
}
public function process_payment($order_id) {
$order = Order::get_order($order_id);
if (!$order || $order->status === 'paid'){
return array (
'result' => 'success',
'redirect' => Order::get_checkout_return_url($order->ID, $this->id)
);
}
if(!$this->is_mobile()){
$url = Order::get_checkout_payment_url($order_id);
return array(
'result' => 'success',
'redirect' => $url,
'height' => '472px',
'modal-size' => 'modal-sm'
);
}
$result = $this->post_payment_api($order);
if(is_wp_error($result)){
return array(
'result' => 'fail',
'msg' => $result->get_error_message(),
'redirect' => Order::get_checkout_return_url($order->ID, $this->id)
);
}else if($result && isset($result['url'])){
return array(
'result' => 'success',
'redirect'=> $result['url']
);
}
}
protected function post_payment_api($order){
if($order && isset($order->ID) && $order->ID){
$data = $this->get_pay_data($order);
$url = $this->_config['tranasction_url'];
try {
$response = $this->http_post($url, wp_json_encode($data));
$result = $response ? json_decode($response, true) : null;
if(!$result){
return new \WP_Error('request_payment_api_err', 'Internal server error');
}
$hash = $this->makeSign($result, $this->_config['secret']);
if(!isset( $result['hash'])|| $hash!=$result['hash']){
return new \WP_Error('request_payment_api_err', __('Invalid sign!', WPCMP_TD));
}
if($result['errcode']!=0){
return new \WP_Error('request_payment_api_err', $result['errcode'] . ' - ' . $result['errmsg']);
}
self::add_log("#" . $order->ID . " 发起虎皮椒支付请求", $this->id);
return $result;
} catch (\Exception $e) {
self::add_log("#".$order->ID." errcode:{$e->getCode()},errmsg:{$e->getMessage()}", $this->id);
return new \WP_Error('request_payment_api_err', $e->getCode() . ' - ' . $e->getMessage());
}
}
}
protected function get_pay_data($order){
if($order && isset($order->ID) && $order->ID){
$total_amount = round($order->price, 2);
$data = array(
'version' => '1.1',
'plugins' => 'wpcom-member-pro',
'appid' => $this->_config['appid'],
'trade_order_id' => $order->number,
'total_fee' => $total_amount,
'title' => $this->get_order_title($order),
'time' => time(),
'notify_url' => Order::get_checkout_notify_url($order->ID, $this->id),
'nonce_str' => $this->getNonceStr()
);
if($this->is_rest && preg_match('/wxpay/i', $this->id)){
$data['type'] = 'JSAPI';
$data['wap_url'] = $this->_config['tranasction_url'];
}else{
$data['return_url'] = Order::get_checkout_return_url($order->ID, $this->id);
$data['callback_url'] = Order::get_checkout_return_url($order->ID, $this->id);
}
if($this->is_mobile() && preg_match('/wxpay/i', $this->id)){
$data['type'] = 'WAP';
$data['wap_url'] = home_url();
$data['wap_name'] = home_url();
}
$data['hash'] = $this->makeSign($data, $this->_config['secret']);
return $data;
}
}
public function check_response($order_id) {
if(!is_numeric($order_id)) return ;
$data = $_POST;
if(!isset($data['hash']) || !isset($data['trade_order_id'])){
return;
}
if(isset($data['plugins']) && $data['plugins']!='wpcom-member-pro'){
return;
}
self::add_log('#虎皮椒异步通知数据:' . wp_json_encode($_POST), $this->id);
$appkey = $this->_config['secret'];
$hash = $this->makeSign($data, $appkey);
if($data['hash']!=$hash){
return;
}
$order = Order::get_order( $order_id );
try{
if(!$order){
throw new \Exception('Unknow Order (id:'.$data['trade_order_id'].', '.$order_id.')');
}
self::add_log('#'.$data['trade_order_id'].' 异步通知验证成功:' . $data['status'] .';虎皮椒订单:' . $data['open_order_id'], $this->id);
if($data['status']=='OD' && $order && $order->number && $order->number == $data['trade_order_id'] && $order->status === 'unpaid'){ // 判断订单号,以及支付状态
Order::payment_complete( $order->ID, $this->id);
self::add_log('#'.$data['trade_order_id'].' 订单支付完成!', $this->id);
echo "success";
}
}catch(\Exception $e){
echo $e->getMessage();
exit;
}
}
protected function http_post($url,$data){
if(!function_exists('curl_init')){
throw new \Exception('php未安装curl组件',500);
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_REFERER,get_option('siteurl'));
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$response = curl_exec($ch);
$httpStatusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$error=curl_error($ch);
curl_close($ch);
if($httpStatusCode!=200){
throw new \Exception("invalid httpstatus:{$httpStatusCode} ,response:$response,detail_error:".$error,$httpStatusCode);
}
return $response;
}
public function makeSign($data, $key){
//签名步骤一:按字典序排序参数
ksort($data);
$string = '';
foreach ($data as $k => $v){
if($k === 'hash' || is_null($v) || $v === ''){continue;}
$string .= $k . "=" . $v . "&";
}
$string = trim($string, "&");
//签名步骤二:在string后加入KEY
$string = $string . $key;
//签名步骤三:MD5加密或者HMAC-SHA256
$string = md5($string);
//签名步骤四:所有字符转为小写
$result = strtolower($string);
return $result;
}
}
new Wxpay_Xunhu();