php paypal ipn,PHP 开发详解:PayPal Instant Payment Notification (IPN)

article/2025/9/13 20:55:03

上次在 PHP 开发详解:PayPal Payment Data Transfer (PDT) 一文中介绍了网站集成 Paypal 付款功能并如何将付款数据返回,能够使得用户在付款完成后继续回到网站上来,并将付款信息告知用户。但是 PayPal Payment Data Transfer 这样的数据返回方式是不保险的,特别是对于用户完成付款后还需要进行后续业务处理,如标注订单为已付款以及减去商品库存等。用户有可能在付款完成后还没跳转到自己网站就已经关闭了页面,而我们的交易数据和业务处理都必须通过访问付款完成后的 ReturnURL 来得到展示与处理。为了获得更加保险的业务处理,我们在集成使用 Paypal 付款功能时需要按需使用 PayPal Instant Payment Notification (IPN)。

PayPal 的开发文档指出:Instant Payment Notification (IPN) is a message service that notifies you of events related to PayPal transactions. You can use IPN messages to automate back-office and administrative functions, such as fulfilling orders, tracking customers, and providing status and other transaction-related information.

同样,在我根据网上部分代码和 PayPal 开发文档开发使用此功能时,遇到了诸多麻烦,不过经过一些时间的探索,也最终实现了 PayPal Instant Payment Notification (IPN) 的集成使用,我也将自己的探究过程和实现方法记录下来,方便读者。如果你在测试或开发中与任何问题或想法欢迎留言交流。

一、PayPal Instant Payment Notification 的工作流程和原理

IPN 是 PayPal 用来通知你相关交易数据的消息服务,它要求你先在自己的 PayPal 商家账户中设置一个即时付款通知 URL 用来接收通知数据,并且编写相应的代码实现特定的数据接收与验证以及可能的业务处理。我们把这个页面或者这些代码称为 listener。顾客在接入了 PayPal 的应用上通过某种方式成功付款。

PayPal 通过 HTTP POST 的方式向你的 listener 发送这次交易的数据和通知。

listener 接收数据并返回一个空的 HTTP 200 响应。

listener 将接收到的通知数据完整的通过 HTTP POST 的方式返回给 PayPal 用于验证。

PayPal 根据接收到的信息进行验证,验证通过返回 VERIFIED,否则返回 INVALID。

完整的工作流程如下图:

12bd9a41c3b4d21b63f1a6e3997056e7.gif

二、申请 PayPal 开发者账号

这在前面文章介绍 PayPal Payment Data Transfer (PDT) 已经有了详细的说明,在此不再赘述。

三、为商家账号启用 IPN 功能

为了使用 PayPal 的 PayPal Instant Payment Notification,必须启用商家账户的实即时付款通知,并设置好的通告 URL。登录 PayPal 账户后,鼠标滑动到【用户信息】处点击【更多选项】,然后找到【即时付款通知习惯设定】,进入设置页面。

点击【选择 IPN 设置】,然后填写好自己的通告 URL,并将【即时付款通知消息】切换为【接收即时付款通知消息(已启用)】,然后点击保存。

这样,我们就设置好了自己的 listener。

四、建立一个 “立即付款” 按钮并集成到自己的应用

这也在前面文章介绍 PayPal Payment Data Transfer (PDT) 已经有了详细的说明,同样不再赘述。

五、获取 IPN 发送过来的交易数据

在我们的 listener 页面,该做的第一件事便是获取 PayPal 发送过来的数据,PayPal 使用 POST 的方式发送数据,我们只需要简单一句代码获取 POST 数据即可:$ipn_post_data = $_POST;

在获取到数据的同时,实际上 listener 已经自动给 PayPal 返回了 HTTP 200 的状态码。

六、向 PayPal 验证交易数据

既然我们已经获取到了 PayPal 使用 POST 的方式发送过来的数据,接下来则必须要原样返回这些数据给 PayPal,用于验证数据的来源和真实性。我们在这里依然使用 cURL 函数进行提交请求数据:// Choose url

if(array_key_exists(‘test_ipn’, $ipn_post_data) && 1 === (int) $ipn_post_data[‘test_ipn’])

$url = ‘https://www.sandbox.paypal.com/cgi-bin/webscr’;

else

$url = ‘https://www.paypal.com/cgi-bin/webscr’;

// Set up request to PayPal

$request = curl_init();

curl_setopt_array($request, array

(

CURLOPT_URL => $url,

CURLOPT_POST => TRUE,

CURLOPT_POSTFIELDS => http_build_query(array(‘cmd’ => ‘_notify-validate’) + $ipn_post_data),

CURLOPT_RETURNTRANSFER => TRUE,

CURLOPT_HEADER => FALSE,

CURLOPT_SSL_VERIFYPEER => TRUE,

CURLOPT_CAINFO => ‘cacert.pem’,

));

// Execute request and get response and status code

$response = curl_exec($request);

$status = curl_getinfo($request, CURLINFO_HTTP_CODE);

// Close connection

curl_close($request);

if($status == 200 && $response == ‘VERIFIED’)

{

// All good! Proceed…

}

else

{

// Not good. Ignore, or log for investigation…

}

在这段代码的最开始设置了对 test_ipn 字段的检测,用于区分测试环境和真实的生产环境,能够方便的应用于测试或者真实生产环境。此外,代码中的 CURLOPT_CAINFO => ‘cacert.pem’,这个证书文件可以前往 http://curl.haxx.se/docs/caextract.html 进行下载。

七、调整编码

经过第六步后,如果我们得到的验证结果是 VERIFIED,接下来就可以使用这些交易信息了。但是有时候我们获得的数据的编码并不是我们所想要的,这时候可能就需要调整数据编码为我们所需要的。一般来说,我们可以将编码调整为 UTF-8。if(array_key_exists(‘charset’, $ipn_data) && ($charset = $ipn_data[‘charset’]))

{

// Ignore if same as our default

if($charset == ‘utf-8’)

return;

// Otherwise convert all the values

foreach($ipn_data as $key => &$value)

{

$value = mb_convert_encoding($value, ‘utf-8’, $charset);

}

// And store the charset values for future reference

$ipn_data[‘charset’] = ‘utf-8’;

$ipn_data[‘charset_original’] = $charset;

}

关于编码,还有一个需要注意的地方,有时候在调试的时候,无论怎么样都无法使交易信息成功通过 IPN 通知到 listener,这个时候可能要考虑 PayPal 的语言编码设置。例如你的网站代码都是 UTF-8 编码,则也应该在【用户信息】【更多选项】【语言编码】的设置页面中点击【更多选项】,将编码调整为 UTF-8。

八、在正式生产环境中使用 PayPal Instant Payment Notification

经过前面的步骤后,我们已经将使用 PayPal Instant Payment Notification 的流程和部分关键代码弄清楚,在开发测试中,首先在 sandbox 中测试通过,然后就可以应用到真实的生产环境了。在真实的生产环境中使用 PayPal Instant Payment Notification 和我们前文所述方法步骤完全一致。

九、示例代码

前文已经详细介绍了 PayPal Instant Payment Notification 的 PHP 开发步骤,中间夹带了部分重要代码片段,由于前面的代码比较分散,为方便大家参考,这里也提供一份示例代码,你可以 访问这里 来获取代码。

至此,PayPal Instant Payment Notification 的 PHP 开发详解已经介绍完毕,希望大家看过有所收获。如果你在阅读过程中发现错误或者对文章有任何观点欢迎留言讨论。最后,此篇文章的形成离不开我在探索过程中所参阅的各种网络资料,对它们的作者表示感谢!


http://chatgpt.dhexx.cn/article/13502soy.shtml

相关文章

【Paypal】即时付款通知IPN

什么是即时付款通知IPN 当您收到新的付款交易或者已发生的付款交易的状态发生变化时,PayPal都将异步(即不作为网站付款流程的一部分) 发送付款详细数据到您所指定的URL,以便您了解买家付款的具体情况并做出相应的响应。这个过程我…

java集成paypal ipn响应问题

在集成paypal 测试ipn如果不回复会多次调用ipn 直到上限或者得到响应。 发现一个非常奇怪的问题代码中未返回响应码,但是paypal那边却显示响应成功? 求大神指点,是因为服务器接收成了吗?所以自动回复了200? spring …

paypal消息通知IPN

paypal支付成功时会实时的把支付交易信息返回给我们,java会返回一个payment对象,里面有交易的信息包含付款人,订单费用,订单的收货地址,收款人,交易号等信息。我们拿到了这个payment就表示支付成功了&#…

paypal资料

什么是即时付款通知IPN 当您收到新的付款交易或者已发生的付款交易的状态发生变化时,PayPal都将异步(即不作为网站付款流程的一部分) 发送付款详细数据到您所指定的URL,以便您了解买家付款的具体情况并做出相应的响应。这个过程我…

css 上下布局 flex,Css Flex布局

Flex布局是Css3中新加入的额外布局系统。 传统布局基于盒模型,依赖“display”、“position”、“float”属性,对于特殊布局非常不便。 因此2009年,W3C提出新的布局方案-Flex布局,但由于浏览器兼容问题,Flex布局并没有大范围铺开。 实现Flex布局的条件 1.必须有一个父级容…

html flex 上中下布局,flex 布局

FlexiableBox即是弹性盒,用来进行弹性布局,一般跟rem(rem伸缩布局(转))连起来用比较方便,flexbox负责处理页面布局,然后rem处理一些flex顾及不到的地方(rem伸缩布局主要处理尺寸的适配问题),布局还是要传统布局的。 布局的传统解决方案,基于盒状模型,依赖display属性 +p…

详细讲解flex布局

一、flex布局基本概念 在没有使用flex布局之前,常用布局有:流式布局,浮动布局,定位布局等等。这些布局的缺陷是子元素需要自己控制自己在父元素中的位置,还要注意父元素高度坍塌。 flex布局是一种布局模型&#xff0…

CSS常用布局二(flex布局)

flex布局 前言:flex是flexible box的缩写,译为“弹性布局”,用来为盒模型提供最大的灵活性,任何一个容器都可以指定为flex布局,只需要设置“display:flex"即可;行内元素可以通过设置”display:inline…

flex布局(详解)

目录 前言 一、何为Flex布局 二、基本概念 三、容器的属性 3.1 flex-direction属性 3.2 flex-wrap属性 3.3 flex-flow 3.4 justify-content属性 3.5 align-items属性 3.6 align-content属性 四、项目的属性 4.1 order属性 4.2 flex-grow属性 4.3 flex-shrink属性 …

Flex布局详解

Flex 布局详解 一、入门 1. flex 是什么? flex 是 Flexible Box 的缩写,就是弹性盒子布局的意思 2. 为什么我们需要 flex? 解决元素居中问题 自动弹性伸缩,合适适配不同大小的屏幕,和移动端 3.flex 常见术语 三个2 序号简…

SQL语句的解析过程

于最近需要做一些sql query性能提升的研究,因此研究了一下sql语句的解决过程。在园子里看了下,大家写了很多相关的文章,大家的侧重点各有不同。本文是我在看了各种资料后手机总结的,会详细的,一步一步地讲述一个sql语句…

SQL学习TASK06

section A 1.创建员工信息表: CREATE TABLE Employee (s_product_id char(4) NOT NULL, s_name VARCHAR(32) NOT NULL, s_salary INTEGER, s_department_id INTEGER); 创建部门信息表: CREATE TABLE department (d_id char(4) NOT NULL, d_name VARCHAR…

MySQL高级SQL语句

目录 一、常用查询 1、按关键字排序 1.1 前期准备 1.2 升序、降序列出数据 1.3 找出其中南京的数据并以分数降序列出 1.4 查询学生信息先按兴趣id降序排列,相同分数的,id也按降序排列 1.5 查询学生信息先按兴趣id降序排列,兴趣id相同的…

HANA 一些sql语句

函数!! 时间函数:DAYS_BETWEEN、ADD_DAYS、FORMAT、CURRENT_DATE、YEAR、MONTH等。 字符串函数:CONCAT、TRIM、LENGTH、REPLACE、STRING_AGG、SUBSTRING等; 数字函数: ROUND、FLOOR、RAND、ABS等 视图&…

SQL语句的封装

本篇供个人学习使用,有问题欢迎讨论 封装SQL语句 ​ 在封装SQL语句之前,我们得知道什么是DAO封装与实体类以及JDBC工具类的封装与连接数据库的具体流程。 ​ 关于JDBC工具类的封装可以查看我的另一篇博文 JDBC工具类的封装 ​ 想了解具体的连接数据库…

mysql sql delete语句_SQL Delete语句

在本教程中,您将学习如何使用SQL DELETE语句删除表中的一行或多行。 1. SQL DELETE语句简介 要从表中删除一行或多行,请使用DELETE语句。 DELETE语句的一般语法如下: DELETE FROM table_name WHERE condition; 首先,提供要删除行的表名称(table_name)。 其次,在WHERE子句中…

MySQL入门(5)——基于datagrip的SQL语句学习

目录 一、什么是SQL二、SQL约束1、主键约束(1)添加主键约束方式一:创建表时,在字段描述处,声明指定字段为主键方式二:创建表时,在constraint约束区域,声明指定字段为主键方式三&…

MySQL数据库增删改查及聚合查询SQL语句学习汇总

目录 数据库增删改查SQL语句 MySQL数据库指令 1.查询数据库 2.创建数据库 3.删除数据库 4.选择数据库 创建表table 查看所有表 创建表 查看指定表的结构 删除表 数据库命令进行注释 增删改查(CRUD)详细说明 增加 SQL库提供了关于时间的…

第一部分_SQL查询语句学习

第一部分 SQL查询语句的学习 单表查询 查询订购日期在1996年7月1日至1996年7月15日之间的订单的订购日期、订单ID、客户ID和雇员ID等字段的值 SELECT 订购日期,订单ID,客户ID,雇员ID FROM 订单 WHERE 订购日期 BETWEEN 1996-07-01 AND 1996-07-15 查询供应商的ID、公司名称、…

了解RS-232、RS-485串口通信协议

文章目录 一、串口通信协议1、RS-232标准2、RS-485标准3、RS232、485电平与TTL电平的区别4、"USB/TTL转232"模块工作原理1、工作流程2、驱动 2、总结3、参考资料 一、串口通信协议 对于通信协议,我们可以分为两个层面进行理解,分别是物理层和…