| Server IP : 43.141.49.107 / Your IP : 113.219.202.141 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;
use WPCOM\Themer\Session;
defined('ABSPATH') || exit;
class Wxpay extends Payment {
private $_config = [];
protected $is_rest = false;
public function __construct() {
$this->id = 'wxpay';
$this->title = '微信支付';
$this->icon = WPCOM_MP_URI . 'payment/wxpay/wxpay.svg';
$this->color = '#2bae67';
$this->modal = !$this->is_mobile(); // 非手机端的时候使用弹框,二维码支付
$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_WXPay_order_status', [$this, 'order_status']);
add_action('wp_ajax_nopriv_WPCOM_WXPay_order_status', [$this, 'order_status']);
parent::__construct();
}
public function init($index){
$appid = wpcom_mp_options('wxpay_appid');
$secret = wpcom_mp_options('wxpay_secret');
$mchid = wpcom_mp_options('wxpay_mchid');
$key = wpcom_mp_options('wxpay_key');
$disable_h5 = wpcom_mp_options('wxpay_disable_h5');
$this->_config = [
'appid' => $appid && isset($appid[$index]) ? trim($appid[$index]) : '',
'mchid' => $mchid && isset($mchid[$index]) ? trim($mchid[$index]) : '',
'key' => $key && isset($key[$index]) ? trim($key[$index]) : '',
'secret' => $secret && isset($secret[$index]) ? trim($secret[$index]) : '',
'disable_h5' => $disable_h5 && isset($disable_h5[$index]) ? $disable_h5[$index] : '',
];
if ($this->is_mobile() && !$this->is_weixin() && $this->_config['disable_h5']) {
// 手机端非微信并且没有开启h5支付时使用二维码扫码支付,改为弹框
$this->modal = true;
}
if(function_exists('WWA_options') && $this->is_rest){
$options = WWA_options();
$this->_config['appid'] = isset($options['appid']) ? trim($options['appid']) : '';
}
}
public function process_payment($order_id) {
$url = Order::get_checkout_payment_url($order_id);
return [
'result' => 'success',
'redirect' => $url,
'height' => '472px',
'modal-size' => 'modal-sm'
];
}
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_wxpay_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 = [
'redirect' => Order::get_checkout_return_url($order->ID, $this->id),
'status' => 'paid'
];
wp_send_json($res);
}
}
}
public function receipt_page($order_id) {
$order = Order::get_order($order_id);
if (!$order || $order->status === 'paid') return;
require_once WPCOM_MP_DIR . "payment/wxpay/WxPay.Config.php";
$config = new WeChat_Config($this->_config);
if($this->is_rest){
include_once WPCOM_MP_DIR . 'payment/wxpay/WxPay.JsApiPay.php';
$tools = new \JsApiPay($config);
$login = new \WWA_REST_Login_Controller();
$str = $login->weapp(['code' => $_POST['code']]);
$openId = isset($str['openid']) && $str['openid'] ? $str['openid'] : '';
$trade_type = 'JSAPI';
}else{
// 手机端、不是微信内打开、未关闭h5支付
if ($this->is_mobile() && !$this->is_weixin() && !$this->_config['disable_h5']) {
require_once WPCOM_MP_DIR . "payment/wxpay/WxPay.Api.php";
$trade_type = 'MWEB';
} else if ($this->is_weixin() && $this->is_mobile() && $this->_config['secret']) { // 使用手机微信内置公众号支付
include_once WPCOM_MP_DIR . 'payment/wxpay/WxPay.JsApiPay.php';
$tools = new \JsApiPay($config);
$openId = $tools->GetOpenid();
$trade_type = 'JSAPI';
} else {
require_once WPCOM_MP_DIR . "payment/wxpay/WxPay.Api.php";
$trade_type = 'NATIVE';
}
}
self::add_log('#' . $order_id . '发起微信支付:' . $trade_type, $this->id);
$input = new \WxPayUnifiedOrder();
$input->SetBody($this->get_order_title($order));
$input->SetOut_trade_no($order->number);
$total = $order->price;
$totalFee = (int) ($total * 100);
$input->SetTotal_fee($totalFee);
$input->SetFee_type('CNY');
$startTime = date("YmdHis", current_time('timestamp'));
$expiredTime = date("YmdHis", current_time('timestamp') + 1800);
$input->SetTime_start($startTime);
$input->SetTime_expire($expiredTime);
$input->SetNotify_url(Order::get_checkout_notify_url($order_id, $this->id));
$input->SetTrade_type($trade_type);
if ($trade_type == 'JSAPI') $input->SetOpenid($openId);
$items = Order::get_order_items($order_id);
if ($items && $items[0] && $items[0]->type_id) {
$product_id = $items[0]->type_id;
} else {
$product_id = $order_id;
}
$input->SetProduct_id($product_id);
try {
if ($trade_type == 'MWEB') {
$result = \WxPayApi::unifiedOrder($config, $input);
$url = isset($result['mweb_url']) ? $result["mweb_url"] : '';
if ($url) {
$url .= '&redirect_url=' . urlencode(Order::get_checkout_return_url($order_id, $this->id));
wp_redirect($url);
exit;
}
} else if ($trade_type == 'NATIVE') {
$result = \WxPayApi::unifiedOrder($config, $input);
$url = isset($result['code_url']) ? $result["code_url"] : '';
} else if ($trade_type == 'JSAPI') {
$result = \WxPayApi::unifiedOrder($config, $input);
$jsApiParameters = $tools->GetJsApiParameters($result);
if($this->is_rest && $jsApiParameters){
$res = json_decode($jsApiParameters, true);
$res['result'] = 0;
$res['order_id'] = $order_id;
Session::set('_rest_wxpay_order_'.$order_id, 'true', 30*60);
wp_send_json($res);
}else{
Session::delete('', '_rest_wxpay_order_'.$order_id);
}
}
$error_msg = '';
if ((isset($result['result_code']) && $result['result_code'] == 'FAIL') || (isset($result['return_code']) && $result['return_code'] == 'FAIL')) {
$error_msg = "返回信息:" . $result['return_msg'] . " ;错误说明:" . (isset($result['err_code_des']) ? $result['err_code_des'] : '');
}
} catch (\Exception $e) {
if($this->update_order_number($order_id, $result)) return false;
$error_msg = '';
if ((isset($result['result_code']) && $result['result_code'] == 'FAIL') || (isset($result['return_code']) && $result['return_code'] == 'FAIL')) {
$error_msg = "返回信息:" . $result['return_msg'] . " ;错误说明:" . $result['err_code_des'];
}
$error_msg = $error_msg ? $error_msg : $e->getMessage();
if($this->is_rest){
$res = [
'result' => -9,
'msg' => $error_msg
];
wp_send_json($res);
}else{
echo '<div class="text-center" style="margin-bottom: 30px;color:#f66;">' . $error_msg . '</div>';
}
return;
}
if($this->update_order_number($order_id, $result)) return false;
?>
<?php if ($error_msg) { ?>
<div class="text-center" style="margin-bottom: 30px;color:#f66;">
<span style="color:red;"><?php echo $error_msg ?></span>
</div>
<?php } else {
if ($trade_type == 'NATIVE') { ?>
<div class="wpcom-wxpay-inner">
<div id="j-wpcom-wxpay" class="wpcom-wxpay-img" data-url="<?php echo $url; ?>" data-order="<?php echo $order_id; ?>"></div>
<p class="wpcom-wxpay-note" style="line-height:2;font-size: 16px;color: #333;">使用微信扫描二维码进行支付</p>
</div>
<?php } else if ($trade_type == 'JSAPI') { ?>
<script type="text/javascript">
window.WPCOM_WXPay_jsApiParameters = <?php echo $jsApiParameters; ?>;
window.onload = function(){WPCOM_WXPay_callpay();}
</script>
<div class="text-center" style="margin-bottom: 30px;padding: 15px 0;">
<button id="j-wpcom-wxpay2" data-order="<?php echo $order_id; ?>" style="width:100%;height:48px;border-radius: 5px;background-color:#44b549; border:0px;color:#fff;font-size:16px;line-height: 48px;padding: 0;" type="button" onclick="WPCOM_WXPay_callpay();">立即支付</button>
</div>
<?php }
} ?>
<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_wxpay_receipt_page');?>"; </script>
<?php }
public function check_response($order_id) {
if(!is_numeric($order_id)) return ;
self::add_log('#'.$order_id.' 微信异步通知开始', $this->id);
$xml = file_get_contents('php://input');
if(empty($xml)) exit;
//排除非微信回调
if(strpos($xml, 'transaction_id')===false
||strpos($xml, 'appid')===false
||strpos($xml, 'mch_id')===false) exit;
require_once WPCOM_MP_DIR . 'payment/wxpay/WxPay.Config.php';
include_once WPCOM_MP_DIR . 'payment/wxpay/notify.php';
// 如果返回成功则验证签名
try {
$is_rest = Session::get('_rest_wxpay_order_'.$order_id);
if(function_exists('WWA_options') && $is_rest){
$options = WWA_options();
$this->_config['appid'] = isset($options['appid']) ? trim($options['appid']) : '';
}
$config = new WeChat_Config($this->_config);
$notify = new \PayNotifyCallBack();
$result = $notify->Handle($config, false);
$values = $notify->FromXml($xml);
self::add_log('#'.$values['out_trade_no'].' 微信异步通知数据:' . wp_json_encode($values), $this->id);
if($result && $values['return_code'] === 'SUCCESS' && $values['result_code'] === 'SUCCESS') {
self::add_log('#'.$values['out_trade_no'].' 微信异步通知验证成功:' . $values['result_code'] .';微信订单:' . $values['transaction_id'], $this->id);
$order = Order::get_order( $order_id );
if($order && $order->number && $order->number == $values['out_trade_no'] && $order->status === 'unpaid'){ // 判断订单号,以及支付状态
Order::payment_complete( $order->ID, $this->id);
self::add_log('#'.$values['out_trade_no'].' 订单支付完成!', $this->id);
}
}
exit;
} catch ( \WechatPaymentException $e ) {
exit;
}
}
function update_order_number($order_id, $result){
if(isset($result["err_code_des"]) && $result["err_code_des"] === '201 商户订单号重复') {
if(Order::update_order_number($order_id)){
self::add_log('#'.$order_id.' 微信订单号重复,更新订单号并重新发起支付', $this->id);
$this->receipt_page($order_id);
return true;
}
}
return false;
}
function is_weixin() {
$ua = strtolower($_SERVER['HTTP_USER_AGENT'] ?? '');
return strpos($ua, 'micromessenger') !== false;
}
}
new Wxpay();