我正在尝试将现有的支付平台集成到我的网上商店。成功完成交易后,支付平台会向我的应用程序中的URL发送请求,并在查询参数中包含事务ID。
但是,我需要进行一些后期处理,例如发送订单确认等。为了做到这一点,我需要访问用户的会话,因为那里存储了许多与订单相关的信息。为此,我将session_id包含在初始请求XML中,并在事务完成后执行以下操作:
$sessionId = 'foo'; // the sessionId is succesfully retrieved from the XML response
session_id($sessionId);
session_start();
上面的代码运行正常,但$_SESSION
仍为空。我忽视了一些事情或者这根本不可能吗?
修改
感谢所有答案。问题尚未解决。如上所述,奇怪的是我可以使用属于下订单的用户的session_id成功启动新会话。还有其他想法吗?
答案 0 :(得分:4)
不是您要求的,但在将客户发送到付款服务之前,您是否需要将订单保留在数据库中?当您收到付款确认后,最好在订单后处理时依赖持久数据。
依靠会话是不可靠的,因为你不知道这个确认需要多长时间(通常是即时的,但在极少数情况下会有延迟)。
此外,如果您的网络服务器在此时间段内重新启动,则会丢失相关数据。
第三个问题是,如果您有一个负载平衡解决方案,具有单独的会话管理(非常常见),那么您将无法保证支付服务器和您的客户端将到达同一个Web服务器(因为粘性通常来源-ip based)。
答案 1 :(得分:3)
我会冒昧地猜测,因为域名与会话设置到您尝试阅读的位置不同,所以php正在安全地播放,而不是检索由不同域设置的会话数据。它是为了保护安全性,以防有人猜测会话ID并劫持数据。
假设交换发生在同一物理磁盘上,解决此问题的方法是临时将订单数据写入序列化(并且可能加密,具体取决于是否正在跟踪完整的信用卡号,这是另一个故事)一旦被接收端读取的文件被立即删除。
从本质上讲,所有这一切都会重复您试图摆脱会话的功能而不会产生恼人的安全副作用。
答案 2 :(得分:1)
非常感谢所有回复。
Smazurov's answer让我思考并让我再次忽略了我的PHP配置。
PHP的默认行为是不加密与会话相关的数据, 可以在重新启动来自其他客户端的旧会话后读取会话数据。但是,我使用Suhosin来修补并防止出现一些安全问题。 Suhosin的默认行为是encrypt session data based on the User Agent,这使得阅读其他人的会话变得更加困难。
这也是我问题的原因;禁用此行为已解决了此问题。
答案 3 :(得分:0)
确保在尝试启动新会话之前关闭当前会话。所以你应该这样做:
$id = 'abc123';
session_write_close();
session_id($id);
session_start();
答案 4 :(得分:-1)
很脏,但对我有用:
告知付款网关使用
http://yourdomain.com/callbackurl.php?PHPSESSID=SESSIONIDHERE
如果设置了某些配置变量(session.use_trans_sid),PHP会使用该方法传递会话,即使已经告知PHP不这样做,它似乎也能正常工作。它当然一直对我有用。
编辑:
您的问题可能是您将session.auto_start设置为true - 因此会话在代码运行之前使用它生成的任何ID自动启动。
答案 5 :(得分:-1)
如何在另一个PHP页面中执行此操作,并在iframe中包含/重定向用户到第二页?
答案 6 :(得分:-1)
我不确定您的交易和支票之间的确切时间长短;但是你的会话cookie肯定已经过期了。默认情况下,会话通常在45分钟左右到期。这是为了释放更多用于php的uniqid,并防止潜在的会话劫持。
我不确定你是否有一个自定义会话处理程序以及它是否存储在数据库中,但是从你在这个页面上的帖子和评论中猜测我会假设它存储在服务器端cookie中。
现在解决您的问题的方法是咬住子弹并将必要的数据存储在数据库中并通过会话ID访问它,即使这意味着创建另一个表位于订单表旁边。
如果您正在立即执行操作,则另一种解释是用户注销或提交了一个销毁其会话的操作(删除服务器端cookie)。
您将在servers / tmp文件夹中看到这些cookie,尝试查看您的cookie,它应命名为'sess'+ $ session_id。