使用基于自定义Woocommerce表单的网关处理付款后收到的数据



我正试图在我的Wooccommerce网站中添加一个自定义支付网关。流程如下:

  1. 用户单击"下订单"按钮后,他将被重定向到我的支付处理器的托管支付页面(HPP(。为了实现这一点,我必须通过一个隐藏的表单发送一些数据(如商家id、哈希、订单金额等(,支付处理器需要将其重定向到HPP
  2. 在HPP中,有一个表单,用户可以在其中介绍他的卡数据
  3. 如果一切正常,用户会被重定向到感谢页面,否则他将被重定向到失败页面,或者出现错误消息,我不在乎

这就是我迄今为止所取得的成就:当用户点击"下订单"时,会创建一个状态为"暂停"的新订单,并将其重定向到一个名为"prueba.php"的页面。该页面仅包含隐藏表单,其中包含支付处理程序将用户重定向到其网关所需的数据。这个表单在页面加载后会自动提交(我觉得这不是最安全的做法,因为如果你打开元素检查器,你可以看到隐藏的输入及其值,但我不知道其他更好的方法来实现这一点(。这是我在插件的主文件中的内容:

add_action( 'plugins_loaded', 'custom_init_gateway_class' );
function custom_init_gateway_class() {
class WC_My_Gateway extends WC_Payment_Gateway {
/**
* Constructor
*/
public function __construct() {
$this->id = 'mygateway';
$this->has_fields = true;
$this->method_title = 'My Gateway';
$this->method_description = 'Description of payment gateway'; 
$this->supports = array(
'products'
);
// Method 
$this->init_form_fields();
$this->init_settings();
$this->title = $this->get_option( 'title' );
$this->description = $this->get_option( 'description' );
$this->enabled = $this->get_option( 'enabled' );
add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) );
}
/**
* Plugin options
*/
public function init_form_fields(){
$this->form_fields = array(
'enabled' => array(
'title' => __( 'Enable/Disable', 'woocommerce' ),
'type' => 'checkbox',
'label' => __( 'Enable Card Payment', 'woocommerce' ),
'default' => 'yes'
),
'title' => array(
'title' => __( 'Title', 'woocommerce' ),
'type' => 'text',
'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce' ),
'default' => __( 'Credit Payment', 'woocommerce' ),
'desc_tip'      => true,
),
'description' => array(
'title' => __( 'Customer Message', 'woocommerce' ),
'type' => 'textarea',
'default' => ''
)
);
}
/*
* Processing the payments
*/
public function process_payment( $order_id ) {
global $woocommerce;
$order = new WC_Order( $order_id );
$order->update_status('on-hold', __( 'Awaiting card payment', 'woocommerce' ));
return array(
'result' => 'success',
'redirect' => 'https://mydomain.example/prueba.php?price='.$order->get_total().'&currency='.$order->get_currency().'&order_id='.$order->get_id()
);
}
}
}
function custom_add_gateway_class( $methods ) {
$methods[] = 'WC_My_Gateway'; 
return $methods;
}
add_filter( 'woocommerce_payment_gateways', 'custom_add_gateway_class' );

"prueba.php"中的隐藏表单。在输入"MERCHANT_REPONSE_URL"中,我必须指定付款处理器在付款完成后将数据发送到哪个URL:

<form method="POST" action="https://paymentprocessorgateway.example" name="respuesta" style="display: none;">
<input type="hidden" name="TIMESTAMP" value="<?php echo $timestamp; ?>">
<input type="hidden" name="MERCHANT_ID" value="12345">
<input type="hidden" name="AMOUNT" value="<?php echo $Amount; ?>">
<input type="hidden" name="CURRENCY" value="<?php echo $Currency; ?>">
<input type="hidden" name="SIGNATURE" value="<?php echo $hash; ?>">
<input type="hidden" name="COMMENT1" value="<?php echo $order_id; ?>">
<input type="hidden" name="MERCHANT_RESPONSE_URL" value="https://mydomain.example/response.php">
<input type="submit" value="Click here to buy">
</form>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script type="text/javascript">
function sendForm() {   
$("form").submit();  
}
sendForm();
</script>

发送此表单后,用户被重定向到支付处理器网关,在那里他可以写入和发送他的卡数据,然后处理器将一些POST数据发送到"response.php"。在这个页面中,我将从支付处理器收到的哈希与我自己生成的哈希(以及从支付处理器接收的其他一些POST值(进行比较。

我想实现的是将用户重定向到感谢页面,如果一切都正确,则将订单状态更改为"已完成",如果不正确,则显示错误消息。此外,我希望在这里创建订单(如果付款正确的话(,而不是当客户点击"下订单"按钮时(我认为知道订单的id,我就可以在任何需要的地方更改其状态,或者我可以在任何地方创建新订单,但我一定做错了,因为我不太清楚wooccommerce和OOP PHP是如何工作的(。我试着在"response.php"中写这篇文章,但处理器的网关抛出了一个错误,说事务进行得很顺利,但它无法连接到MERCHANT_REPONSE_url:中指定的url

//Generating the hash with data received from processor
$respuesta = $_POST['TIMESTAMP'].".".$_POST['MERCHANT_ID'].".".$_POST['ORDER_ID'].".".$_POST['RESULT'];
$my_hash = sha1(sha1($respuesta);
global $woocommerce;
$order = wc_get_order( $order_id );
if ($my_hash != $_POST['HASH']) { //$_POST['HASH'] is the hash sent by the processor.
wc_add_notice(  'Please try again.', 'error' );
return;
} else {
$order->payment_complete();
$woocommerce->cart->empty_cart();
return array(
'result' => 'success',
'redirect' => $this->get_return_url( $order )
);
}

如果我删除了与wooccommerce相关的变量,并使用类似的东西来查看它是否工作,则会正确打印警报:

if ($my_hash != $_POST['HASH']) {
echo '<script>alert("Wrong transaction");</script>';
} else {
echo '<script>alert("Correct transaction");</script>';
}

这就像我不能在那里使用与wooccommerce相关的变量。我想我一定要把它挂在钩子上什么的,但我不知道是哪一个,也不知道在哪里,我觉得我一路上犯了很多错误。如果有人能告诉我如何处理支付处理器的响应,并将其与Wooccommerce流集成,我将永远感激。

首先。如果你应该提交一个隐藏的表单,当涉及到隐藏或不隐藏方面时,我不会担心安全性。任何客户端的东西都可以被查看/篡改,所以这不是我应该采取的安全措施。

您的最后一块代码提到$old_hash,但它是空的?至少,你的代码块没有设置它。你说这个代码的哪一部分不起作用?你有没有试着登录到类似的错误日志中,看看它是否被调用?(类似error_log('message');(

你提到HPP会向你选择的页面发送一个散列,所以我想说response.php可能是用户付费后发送的页面。

(另外,对我来说,现在几乎是睡觉时间了,所以如果我停止回应,我很抱歉。(

最新更新