您必须以某种方式创建一个流程,以确保用户按照正确的顺序遵循所需步骤,并防止他跳出此顺序。
跟踪用户会话中的步骤似乎是很自然的事情。如果会话不允许请求的步骤,请将其重定向到别处而不是询问贝宝。
豪华版本将为您实现状态机,以便日后更轻松地进行改进。状态机一开始就面临着巨大的开销,如果你最初采取了不同的方法,那么稍后实施起来会很麻烦。这就是为什么从一开始就考虑使用它的原因。
如果您希望稍后添加其他支付提供商,该怎么办?一台状态机可以很容易地扩展 - 其他任何东西都可能是一团糟。
编辑: 其实,paypal希望您在用户返回您的网站后发送给他们的唯一东西就是您要收取的金额。这些信息可以通过将其发送到您发送给PayPal的返回网址来传递。尝试在那里添加一些校验和以防止数据错误和容易篡改(如果数量不正确,Paypal可以让流程失败),并且基本完成。根本不需要任何会话。
Edit2:这里是我的代码片段,它定义了paypal第一步的nvp参数。你也需要必要的认证资料。
public function preparePayment(...) {
$nvp = array(
'METHOD' => 'SetExpressCheckout',
'VERSION' => '52.0',
'RETURNURL' => 'https://'.$request->server['HTTP_HOST'].'/'.$request->getLanguage().'/paypal/success/'.$this->hashAmount($amount),
'CANCELURL' => 'https://'.$request->server['HTTP_HOST'].'/'.$request->getLanguage().'/paypal/cancel',
'CURRENCYCODE' => $amount->getCurrency(),
'AMT' => number_format($amount->getAmount(), 2, '.', ''),
'ITEMAMT' => number_format($amount->getNettoAmount(), 2, '.', ''),
'TAXAMT' => number_format($amount->getVatAmount(), 2, '.', ''),
'PAYMENTACTION' => 'Sale',
'LOCALECODE' => strtoupper($request->getLanguage())
);
}
protected function hashAmount(Currency_Class $amount) {
return urlencode(
sprintf(
'%s-%s-%s-%u',
number_format($amount->getNettoAmount(), 2, '', ''),
number_format($amount->getVatAmount(), 2, '', ''),
strtoupper($amount->getCurrency()),
$this->makeChecksumString(number_format($amount->getNettoAmount(), 2, '', ''), strtoupper($amount->getCurrency()))
)
);
}
protected function makeChecksumString($amount, $currency) {
return crc32(sprintf('%sSaltValue%s', $amount, $currency));
}
protected function dehashAmount($string) {
$parts = array();
$found = preg_match('/^(\d+)\-(\d+)\-([A-Z]+)\-(\d+)$/', $string, $parts);
if ($found) {
$check = sprintf('%u', $this->makeChecksumString($parts[1], $parts[3]));
if ($check == $parts[4]) {
$netto = floatval(substr($parts[1], 0, -2) .'.'. substr($parts[1], -2));
$vat = floatval(substr($parts[2], 0, -2) .'.'. substr($parts[2], -2));
}
}
return ...
}
我不明白什么是状态机;管理费用?不可能!并且由于快速结账流程(从购物车直接到贝宝)没有第一步;我的第一个问题是,发送购物车金额到PayPal的页面需要无法访问,除非按下购物车上的PayPal按钮。我怎样才能做到这一点? – Ozzy
我们现在是否在您的第一页上留言 - 在图表中左下角标有“购物车”的那一页?如果不满足所有要求,则不会将请求发送到PayPal应该很容易。金额为零?没有贝宝。按钮没有按下?没有贝宝。任何其他错误?没有贝宝。 – Sven
正如我在我的文章中所说'我知道我可以在购物车页面上设置另一个会话变量,以确保他们首先访问购物车,然后在检查后清除变量,但是另一个问题是用户只需要访问购物车页面一次,变量将被设置为允许他们访问发送令牌请求到paypal的敏感页面。“但是从不知道我想它不是一个大问题 – Ozzy