70

我正在为 Magento 实施一个新的支付模块,并想了解这个逻辑背后的核心概念。我知道我必须从 Mage_Payment_Model_Method_Abstract 或其任何子类扩展,但我的问题是何时使用以及如何在我的模型中使用捕获和授权方法。例如,如果我将整个过程分成如下步骤:

  1. 用户来到购物车并选择让我们说一些支付方式,即网关。
  2. 系统拦截请求,收集所有提交的数据并将用户发送到网关 url。
  3. 用户在网关站点下订单(或取消),网关站点将有关它的信息发送到我的商店。
  4. 我的商店使用收到的数据对订单进行了更多修改,并保存状态为已完成或已取消的订单。

在这些步骤中,我必须在哪里使用授权和捕获方法?如果有人可以向我解释授权和捕获的含义,我将不胜感激?

4

1 回答 1

150

这是我一直以来理解这些概念的方式,以及在 Magento 中实现支付模块需要了解的内容。下面以粗体显示您的具体“这发生在哪里”的答案,尽管它并不像您希望的那么简单。

互联网前的实体信用卡交易是一个两阶段的过程。

在销售时,当商家拿消费者的信用卡进行购买时,他们会将其滑过一个销售点设备,该设备会呼叫信用卡的中央办公室并询问“这张卡是否被授权用于该网络,并且这个特定消费者的可用信用额度是否足够大以允许进行此购买”。

如果购买被接受(而不是被拒绝),则该费用被认为是授权的。消费者会拿走他们的产品,销售点系统/收银机会注意到交易是经过授权的。然后,在一天结束或一周结束时,在其他预定的定期时间表,或者当所有者决定停止饮酒时,商家将查看他们所有的授权收据并向中心办公室发送另一个请求从授权交易中获取资金。获取资金就是将钱存入商家账户的原因。

这仍然是大多数网关使用的模型,也是 Magento Inc. 选择为其支付模块实施的域模型。

事情应该运行的方式是,当消费者到达像 Magento 这样的系统中的最后结帐步骤时,Magento 会向网关的 API 发出授权请求。如果交易成功,订单将被系统接受,并存储来自授权请求的唯一 ID。接下来,当消费者的商品发货时,店主使用 Magento 管理员创建发票。此发票的创建发出一个捕获请求(使用从授权请求返回的商店 ID)。 这是在 Magento 中发出这些方法调用的地方

然而,事情变得棘手,因为每个支付网关对这些概念的解释都略有不同,每个商家对他们“在我们发货之前不要捕获”的责任的解释也不同。除了上述场景之外,支付模块还有一个称为支付操作的系统配置值。这可以设置为Authorize Only,这将实现上述流程。它也可以设置为Authorize 和 Capture,这将在下订单时授权和捕获付款。它变得更加令人困惑,因为虽然该方法称为 Authorize 和 Capture,但当前版本的 Magento 只会在设置为这种模式时发出捕获请求(至少对于 Authorize.net 而言),并且 Authorize.net 将在内部将捕获请求保留在授权但一天中的大部分时间都没有捕获状态。Magento 如何处理订单、付款和发票是代码库的一个领域,它在不同版本之间发生了很大变化。

因此,Magento 支付模块系统背后的想法是保护您免受集群 F 的影响——即编程支付网关逻辑。在您的authorize方法中,您实现了对支付网关的授权 API 的调用(或执行您希望此时发生的任何检查和逻辑)。这个方法传递了一个支付对象和一个金额。如果您让您请求/执行您的逻辑并确定它因任何原因无效,您将抛出一个异常

Mage::throwException('...');

这告诉 Magento 授权失败,它会采取相应的行动(显示错误消息等)。否则,您在 Payment 对象上设置数据成员并发出

return $this;

数据成员是您稍后在捕获付款时需要的东西。这将我们带到了capture您的付款模块的方法。此方法还发送一个支付对象和一个金额。在此方法中,您发出捕获请求。支付对象将具有cc_trans_id数据成员

$payment->getCcTransId()

这将允许您针对网关发出捕获。这是您负责保存的数据成员之一authorize。同样,如果您的代码确定捕获失败,则会引发异常。否则,你return $this

authorize.net 支付模块有很好的例子来说明如何做到这一点。

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

例如,考虑这部分capture方法

public function capture(Varien_Object $payment, $amount)
{
    if ($payment->getCcTransId()) {
        $payment->setAnetTransType(self::REQUEST_TYPE_PRIOR_AUTH_CAPTURE);
    } else {
        $payment->setAnetTransType(self::REQUEST_TYPE_AUTH_CAPTURE);
    }   

    $payment->setAmount($amount);
    $request= $this->_buildRequest($payment);
    $result = $this->_postRequest($request);
    //...

这里的捕获方法是检查付款是否有cc_trans_id. 根据结果​​,它设置anet_trans_type为:

self::REQUEST_TYPE_PRIOR_AUTH_CAPTURE
self::REQUEST_TYPE_AUTH_CAPTURE

然后 API 请求对象使用此值来发送 API 调用

  1. 捕获预授权交易
  2. 立即捕获

希望对您有所帮助,祝您好运!

于 2011-03-20T19:22:50.327 回答