使用POST身份验证重定向到第三方支付网关

时间:2013-02-03 19:05:49

标签: xml magento payment-gateway

我在Magento中有一个几乎完整的自定义付款方式解决方案。我按照[this] http://www.junaidbhura.com/how-to-make-a-custom-magento-payment-extension-for-an-external-gateway/关于如何做的优秀教程,但我现在遇到了身份验证问题。

我联系了网关,一位IT代表告诉我,我必须将正确的值发布到网关进行身份验证。这些值也必须以XML格式发送:

Testmode用户名:###### 测试模式密码:###### Testmode MerchantID:##### Testmode TerminalID:##### BIN = ###### 1

我在网关模块中使用正确的字段创建了一个system.xml:

<?xml version="1.0"?>
<config>
  <sections>
    <payment>
      <groups>
        <mygateway translate="label comment" module="mygateway">
          <label>My Module mygateway</label>
          <frontend_type>text</frontend_type>
          <sort_order>0</sort_order>
          <show_in_default>1</show_in_default>
          <show_in_website>1</show_in_website>
          <show_in_store>1</show_in_store>
          <fields>
            <active translate="label">
              <label>Enabled</label>
              <frontend_type>select</frontend_type>
              <source_model>adminhtml/system_config_source_yesno</source_model>
              <sort_order>10</sort_order>
              <show_in_default>1</show_in_default>
              <show_in_website>1</show_in_website>
              <show_in_store>0</show_in_store>
            </active>
            <title translate="label">
              <label>My Module mygateway Paymentech</label>
              <frontend_type>text</frontend_type>
              <sort_order>20</sort_order>
              <show_in_default>1</show_in_default>
              <show_in_website>1</show_in_website>
              <show_in_store>1</show_in_store>
            </title>
            <order_status translate="label">
              <label>New Order Status</label>
              <frontend_type>select</frontend_type>
              <source_model>adminhtml/system_config_source_order_status</source_model>
              <sort_order>50</sort_order>
              <show_in_default>1</show_in_default>
              <show_in_website>1</show_in_website>
              <show_in_store>0</show_in_store>
            </order_status>
            <allowspecific translate="label">
              <label>Payment Applicable From</label>
              <frontend_type>select</frontend_type>
              <sort_order>61</sort_order>
              <source_model>adminhtml/system_config_source_payment_allspecificcountries</source_model>
              <show_in_default>1</show_in_default>
              <show_in_website>1</show_in_website>
              <show_in_store>0</show_in_store>
            </allowspecific>
            <specificcountry translate="label">
              <label>Countries Payment Applicable From</label>
              <frontend_type>multiselect</frontend_type>
              <sort_order>70</sort_order>
              <source_model>adminhtml/system_config_source_country</source_model>
              <show_in_default>1</show_in_default>
              <show_in_website>1</show_in_website>
              <show_in_store>0</show_in_store>
              <depends>
                <allowspecific>1</allowspecific>
              </depends>
            </specificcountry>
            <sort_order translate="label">
              <label>Sort Order</label>
              <frontend_type>text</frontend_type>
            </sort_order>
            <sort_order>100</sort_order>
            <show_in_default>1</show_in_default>
            <show_in_website>1</show_in_website>
            <show_in_store>0</show_in_store>
            <test_apiusername translate="label">
                            <label>Test Mode Username</label>
                            <frontend_type>text</frontend_type>
                            <sort_order>6</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>1</show_in_store>
                        </test_apiusername>
                        <test_apipassword translate="label">
                            <label>Test Mode Password</label>
                            <frontend_type>obscure</frontend_type>
                            <backend_model>adminhtml/system_config_backend_encrypted</backend_model>
                            <sort_order>7</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>1</show_in_store>
                        </test_apipassword>
                        <test_MerchantID translate="label">
                            <label>Test Mode MerchantID</label>
                            <frontend_type>text</frontend_type>
                            <sort_order>8</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>1</show_in_store>
                        </test_MerchantID>
                        <test_TerminalID translate="label">
                            <label>Test Mode TerminalID</label>
                            <frontend_type>text</frontend_type>
                            <sort_order>9</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>1</show_in_store>
                        </test_TerminalID>
                        <test_BINNumber translate="label">
                            <label>Test Mode BIN</label>
                            <frontend_type>text</frontend_type>
                            <sort_order>10</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>1</show_in_store>
                        </test_BINNumber>
                        <test_cgi_url>
                            <label>Test Mode Gateway URL</label>
                            <frontend_type>text</frontend_type>
                        <sort_order>11</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>1</show_in_store>
                        <comment>Above values should be entered for Test account</comment>
                        </test_cgi_url>
                        <apiusername translate="label">
                            <label><![CDATA[<strong>Production</strong>]]> Mode Username</label>
                            <frontend_type>text</frontend_type>
                            <sort_order>12</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>1</show_in_store>
                        </apiusername>
                        <apipassword translate="label">
                            <label><![CDATA[<strong>Production</strong>]]> Mode Password</label>
                            <frontend_type>obscure</frontend_type>
                            <backend_model>adminhtml/system_config_backend_encrypted</backend_model>
                            <sort_order>13</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>1</show_in_store>
                        </apipassword>
                        <MerchantID translate="label">
                            <label><![CDATA[<strong>Production</strong>]]> Mode MerchantID</label>
                            <frontend_type>text</frontend_type>
                        <sort_order>14</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>1</show_in_store>
                        </MerchantID>
                        <TerminalID translate="label">
                            <label><![CDATA[<strong>Production</strong>]]> Mode TerminalID</label>
                            <frontend_type>text</frontend_type>
                        <sort_order>15</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>1</show_in_store>
                        </TerminalID>
                        <BINNumber translate="label">
                            <label><![CDATA[<strong>Production</strong>]]> Mode BIN</label>
                            <frontend_type>text</frontend_type>
                        <sort_order>16</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>1</show_in_store>
                        </BINNumber>
          </fields>
        </mygateway>
      </groups>
    </payment>
  </sections>
</config>

我不确定在PaymentController.php

中进行身份验证所需的POST值的实现
<?php

class Myname_Mygateway_PaymentController extends Mage_Core_Controller_Front_Action {
    // The redirect action is triggered when someone places an order
    public function redirectAction() {
        $this->loadLayout();
        $block = $this->getLayout()->createBlock('Mage_Core_Block_Template','mygateway',array('template' => 'mygateway/redirect.phtml'));
        $this->getLayout()->getBlock('content')->append($block);
        $this->renderLayout();
    }

    // The response action is triggered when your gateway sends back a response after processing the customer's payment
    public function responseAction() {
        if($this->getRequest()->isPost()) {

            /*
            /* Your gateway's code to make sure the reponse you
            /* just got is from the gatway and not from some weirdo.
            /* This generally has some checksum or other checks,
            /* and is provided by the gateway.
            /* For now, we assume that the gateway's response is valid
            */

            $validated = true;
            $orderId = '123'; // Generally sent by gateway

            if($validated) {
                // Payment was successful, so update the order's state, send order email and move to the success page
                $order = Mage::getModel('sales/order');
                $order->loadByIncrementId($orderId);
                $order->setState(Mage_Sales_Model_Order::STATE_PROCESSING, true, 'Gateway has authorized the payment.');

                $order->sendNewOrderEmail();
                $order->setEmailSent(true);

                $order->save();

                Mage::getSingleton('checkout/session')->unsQuoteId();

                Mage_Core_Controller_Varien_Action::_redirect('checkout/onepage/success', array('_secure'=>true));
            }
            else {
                // There is a problem in the response we got
                $this->cancelAction();
                Mage_Core_Controller_Varien_Action::_redirect('checkout/onepage/failure', array('_secure'=>true));
            }
        }
        else
            Mage_Core_Controller_Varien_Action::_redirect('');
    }

    // The cancel action is triggered when an order is to be cancelled
    public function cancelAction() {
        if (Mage::getSingleton('checkout/session')->getLastRealOrderId()) {
            $order = Mage::getModel('sales/order')->loadByIncrementId(Mage::getSingleton('checkout/session')->getLastRealOrderId());
            if($order->getId()) {
                // Flag the order as 'cancelled' and save it
                $order->cancel()->setState(Mage_Sales_Model_Order::STATE_CANCELED, true, 'Gateway has declined the payment.')->save();
            }
        }
    }
}

最后是重定向的表单,即redirect.phtml

<?php
// Retrieve order
$_order = new Mage_Sales_Model_Order();
$orderId = Mage::getSingleton('checkout/session')->getLastRealOrderId();
$_order->loadByIncrementId($orderId);
?>
<form name="mygatewayform" method="post" action="http://www.gateway.com/the_url_they_gave_me">
    <input type="hidden" name="orderid" value="<?php echo $orderId; ?>">
    <input type="hidden" name="grandtotal" value="<?php echo $_order->getBaseGrandTotal(); ?>">
</form>
<script type="text/javascript">
document.mygatewayform.submit();
</script>

我能够运行测试订单但网关仅因IP记录而收到我的订单,而且格式不正确。在发布此处之前,我一直在搜索Magento论坛和谷歌近三周,但我找不到任何解决方案。网关无法提供帮助,因为没有可用的Magento集成手册。

如果不是太麻烦,我会非常感激一些帮助......

1 个答案:

答案 0 :(得分:1)

以下用于创建将重定向到第三方网关的付款的说明。

The URL that the payment gateway needs to redirect to on your web site after processing the customer’s payment (based on the naming we’ve used in this example) should be: http://www.yourwebsite.com/mygateway/payment/response .

完成您要完成的工作的最佳方式是遵循此http://www.excellencemagentoblog.com/magento-create-custom-payment-method-api-based

另见

  

/app/code/core/Mage/Paygate/Model/Authorizenet.php

//create xml and send info to gateway
private function callApi(Varien_Object $payment, $amount,$type){

    //call your authorize api here, incase of error throw exception.
    //only example code written below to show flow of code

    /*
     $order = $payment->getOrder();
    $types = Mage::getSingleton('payment/config')->getCcTypes();
    if (isset($types[$payment->getCcType()])) {
    $type = $types[$payment->getCcType()];
    }
    $billingaddress = $order->getBillingAddress();
    $totals = number_format($amount, 2, '.', '');
    $orderId = $order->getIncrementId();
    $currencyDesc = $order->getBaseCurrencyCode();

    $url = $this->getConfigData('gateway_url');
    $fields = array(
            'api_username'=> $this->getConfigData('api_username'),
            'api_password'=> $this->getConfigData('api_password'),
            ......

            'customer_firstname'=> $billingaddress->getData('firstname'),
            'customer_lastname'=> $billingaddress->getData('lastname'),
            'customer_phone'=> $billingaddress->getData('telephone'),
            'customer_email'=> $billingaddress->getData('email'),
            'customer_ipaddress'=> $_SERVER['REMOTE_ADDR'],
            'bill_firstname'=> $billingaddress->getData('firstname'),
            'bill_lastname'=> $billingaddress->getData('lastname'),
            'Bill_address1'=> $billingaddress->getData('street'),
            'bill_city'=> $billingaddress->getData('city'),
            'bill_country'=> $billingaddress->getData('country_id'),
            'bill_state'=> $billingaddress->getData('region'),
            'bill_zip'=> $billingaddress->getData('postcode'),
            'customer_cc_expmo'=> $payment->getCcExpMonth(),
            'customer_cc_expyr'=> $payment->getCcExpYear(),
            'customer_cc_number'=> $payment->getCcNumber(),
            'customer_cc_type'=> strtoupper($type),
            'customer_cc_cvc'=> $payment->getCcCid(),
            'merchant_ref_number'=> $order->getIncrementId(),
            'currencydesc'=>$currencyDesc,
            'amount'=>$totals
    );

    $fields_string="";
    foreach($fields as $key=>$value) {
    $fields_string .= $key.'='.$value.'&';
    }
    $fields_string = substr($fields_string,0,-1);
    //open connection
    $ch = curl_init($url);
    //set the url, number of POST vars, POST data
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_POST,1);
    curl_setopt($ch, CURLOPT_POSTFIELDS,$fields_string);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION ,1);
    curl_setopt($ch, CURLOPT_HEADER ,0); // DO NOT RETURN HTTP HEADERS
    curl_setopt($ch, CURLOPT_RETURNTRANSFER ,1); // RETURN THE CONTENTS OF THE CALL
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 120); // Timeout on connect (2 minutes)
    //execute post
    $result = curl_exec($ch);
    curl_close($ch);
    */

    return array('status'=>1,'transaction_id' => time() , 'fraud' => rand(0,1));
}