我正在为Magento实施一个新的支付模块,并希望了解这个逻辑背后的核心概念。我知道我必须从Mage_Payment_Model_Method_Abstract或其任何子类扩展,但我的问题是何时使用以及如何在我的模型中使用捕获和授权方法。
例如,如果我按照以下步骤拆分整个过程:
在这些步骤中,我必须使用授权和捕获方法吗?如果有人能向我解释什么是授权和捕获手段,我将不胜感激?
答案 0 :(得分:148)
以下是我一直理解这些概念的方式,以及在Magento中实施支付模块需要了解的内容。你特定的“这种情况发生在哪里”的答案会在下面加粗,尽管它并不像你希望的那么简单。
互联网前,实体信用卡交易分为两个阶段。
在销售时,当商家拿走消费者的信用卡进行购买时,他们会通过销售点设备将其滑入信用卡的中心办公室并询问“此卡是否已获得授权网络,这是特定消费者的可用信贷额度,足以允许这次购买“。
如果购买被接受(而不是拒绝),则说该费用是授权的。消费者会拿走他们的产品,销售点系统/现金登记处会注意到交易是经过授权的。然后,在一天结束或一周结束时,在某个其他预定的常规时间表,或者当所有者决定停止饮酒时,商家将通过他们所有的授权收据并发送另一个请求中心办公室从授权交易中获取资金。捕获资金是将钱存入商家账户的原因。
这仍然是大多数网关使用的模型,也是Magento Inc.选择为其支付模块实施的域模型。
在Magento这样的系统中,当消费者到达最终结账步骤时,应该运行的方式是,Magento向网关的API发出授权请求。如果交易成功,则订单被接受到系统中,并且存储来自授权请求的唯一ID。接下来,当消费者的货物发货时,商店所有者使用Magento管理员创建发票。创建此发票会发出捕获请求(使用从授权请求返回的商店ID)。 这是在Magento中发布这些方法调用的地方。。
然而,事情变得棘手,因为每个支付网关都会以不同的方式解释这些概念,并且每个商家都会以不同的方式解释他们“在我们发货之前不捕获”的责任。除了上述方案之外,支付模块还具有称为付款操作的系统配置值。这可以设置为仅授权,这将实现上述流程。它也可以设置为授权和捕获,它将在下订单时授权和捕获付款。甚至更多令人困惑,因为虽然该方法称为Authorize and Capture,但当前版本的Magento仅在此模式下设置时发出捕获请求(至少对于Authorize.net)和Authorize.net将在内部将捕获请求保留在授权但未捕获状态的当天大部分时间。 Magento如何处理订单和付款以及发票是代码库中的一个区域,它在版本之间发生了很大的变化。因此,Magento支付模块系统背后的想法是保护您免受Cluster 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调用希望有所帮助,祝你好运!