沙箱环境和正式环境【PayPal接入(java)】【IPN通知问题】项目实战干货总结记录!

article/2025/9/13 20:53:50

如果你是第一次接入paypal,相信本文的每一个地方都会对你有帮助的!!因为这篇文章都是一个一个的坑踩出来的!

一、接入paypal环境准备:

1、注册paypal账号

https://www.paypal.com
注册“商家账号”,完成验证

2、登录paypal开发者平台

用上一步创建好的账号登陆:https://developer.paypal.com

3、创建测试用户和商家账号
在这里插入图片描述
个人和商家账号都选中国就行
在这里插入图片描述

那三个点里面可以设置账号的一些信息,还有余额之类的

4、创建应用,生成用于测试的clientID 和 密钥

当前页面创建应用
在这里插入图片描述
这里面有一个默认的还有一个我已经创建好的测试应用,这里:如果要创建线上账号,点击右侧live,可能需要邮箱验证,可以到自己的邮箱中查看,其他的不变
在这里插入图片描述
点击按钮创建自己的应用,选择好我们之前创建的收款账号
在这里插入图片描述
这样我们的id和密匙都创建好了
在这里插入图片描述

二、使用java(springboot)实现paypal支付:

下面是调接口的方式直接接入

使用基本的web项目即可
pom引入:

<dependency><groupId>com.paypal.sdk</groupId><artifactId>rest-api-sdk</artifactId><version>1.4.2</version>
</dependency>

代码的基本流程:

接口调用→调用service→创建订单→重定向到paypal的页面(后面的支付流程交给了paypal,这个页面就是在那个for循环里面的那个条件甄别出来的那个url,看了下面的代码你才能明白我说的哦)→登录→支付

代码参考(我也是参考这篇文章,自己改造的):https://www.cnblogs.com/jpfss/p/9945845.html

其中的不足:

1、在创建订单的时候:其一在自己的业务系统中有一些必要的信息需要PayPal通知的时候回传,比如id等字段,这个可以放到custom这个字段里面;其二购物车的信息,可以自行理解下面的代码,item→items→itemsList→transaction→transactions

甚至一些收货地址,信息什么的,我都没看到,我这里也没用到,所以我也没关注,需要自己研究下,总之都在这一步,下面的代码是我自己的一些设置,供参考
在这里插入图片描述
2、没有集成通知:

在这里我简单提一下:

登录商家账号:https://www.sandbox.paypal.com/
右上角头像→Account Settings→左侧栏通知→即时通知付款→更新

填写自己的接口:这个接口需要域名哦,可以用内网穿透工具转发哦。
在这里插入图片描述
在代码中怎么做呢?

 @RequestMapping(value = "notify", method = RequestMethod.POST)public void notify(@RequestBody String body, final HttpServletResponse response) throws IOException {//原始请求的body,kv,在回复paypal通知的有用,这里卡了我好久,在后面的问题模块也有提到var kv = URLEncodedUtils.parse(body, Charset.forName("utf-8"));//下面就是转换成我们自己的实体类,用来接收paypal通知的所有字段,如果不知道有什么字段。可以看看body里面具体的内容哦Map<String, String> map = kv.stream().collect(Collectors.toMap(NameValuePair::getName, NameValuePair::getValue));PostPayPalNotifyRequest postPayPalNotifyRequest = PostPayPalNotifyRequest.getInstanceFromMap(map);try {//处理通知payPalPaymentService.handlePayPalPaymentSuccessNotification(postPayPalNotifyRequest, body);response.getWriter().write("success");} catch (DuplicateKeyException exception) {log.warn("payPal notify for order id " + postPayPalNotifyRequest.getTxnId() + " has been already received. ignored! ");}}

处理通知的时候要做什么呢?

参考:https://www.paypal.com/c2/cgi-bin/webscr?cmd=p/acc/ipn-info-outside,这里提一下,网站感觉很久没有维护了,最新的通知回验url为:

#正式环境:
payPal.verifyUrl=https://ipnpb.paypal.com/cgi-bin/webscr
#沙箱环境:
#payPal.verifyUrl=https://ipnpb.sandbox.paypal.com/cgi-bin/webscr

三、我遇到的问题

1、paypal通知(ipn)遇到:支付返回的状态为:Pending

解决:√
在这里插入图片描述
这个页面来源,参考,本文的“接入paypal”的第三步

注意,如果为线上环境,会有一个 “卖家成长计划的限制”,前期的收款状态为:Pending状态,因为钱都是冻结的状态,同事满足三个条件以后,才可以“毕业”,具体条例为下:

  • 1、账户收款满250美金
  • 2、账户收款满10笔交易
  • 3、从您第一次收款往后顺延60天。

在任意一个条件不满足的情况下,每笔收款都会被冻结21天。21天之后会转到余额中。

2、回调通知的时候,得不到 VERIFIED

解决:√

主要需要的cmd=_notify-validate+&+原始通知这个kv来回调的哦
所以我们需要保留原始的body然后加&cmd=_notify-validate

代码参考:这个body前面我们是有拿到的哦

 /*** sandbox为:https://www.sandbox.paypal.com/cgi-bin/webscr* live为:https://www.paypal.com/cgi-bin/webscr* 将paypal发送过来的所有信息加上一个&cmd=_notify-validate参数,表示对这个信息进行验证,全部发送回paypal验证,如果信息确实存在,则返回VERIFIED字符串。** @param request* @return*/public boolean verifyNotify(final PostPayPalNotifyRequest request, final String body) {log.info("开始回调PayPal接口,验证通知...");String callBackBody = "cmd=_notify-validate&" + body;try {String verifyRes = HttpUtils.doPost(verifyUrl, callBackBody, "utf-8");log.info("验证结果为:{}", verifyRes);return verifyRes.equals(VERIFIED);} catch (Exception e) {log.error("payPal验证通知异常" + e.getMessage());}return false;}

这里着重说一下, 这里在上线的时候也遇到了很多坑!!一直收不到VERIFIED,此时我们要注意,以下几个点:

  • 1、原来的字符串的次序不能乱
  • 2、编码问题:打开https://www.paypal.com/cgi-bin/webscr?cmd=_profile-language-encoding用你的账号登陆,设置语言为中文,更多选项里面编码设置为utf-8
    在这里插入图片描述

3、正式环境的切换:

解决:√

更换正式环境的id和密匙,
修改配置文件:
payPal.mode=sandbox为payPal.mode=live

其他

PayPal开发手册

部分PayPal通知的字段含义

github上ipn示例代码

paypal返回的错误字段已经含义对照

例如:{“name”:“INSTRUMENT_DECLINED”,“message”:“The instrument presented was either declined by the processor or bank, or it can’t be used for this payment.”,“information_link”:“https://developer.paypal.com/docs/api/payments/#errors”,“debug_id”:“c16fbeac17bf1”}

联系技术支持的步骤:

  1. 访问www.paypal-support.com
  2. 页面右下方可以将语言更改为中文
  3. 点击“联系我们”
  4. 使用您的PayPal账户登陆后,进行提问
    提问后他们会在3-5个工作日中文邮件回复您的。很抱歉他们是没有在线客服或者电话服务的。

http://chatgpt.dhexx.cn/article/LXGhqPrZ.shtml

相关文章

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

上次在 PHP 开发详解&#xff1a;PayPal Payment Data Transfer (PDT) 一文中介绍了网站集成 Paypal 付款功能并如何将付款数据返回&#xff0c;能够使得用户在付款完成后继续回到网站上来&#xff0c;并将付款信息告知用户。但是 PayPal Payment Data Transfer 这样的数据返回…

【Paypal】即时付款通知IPN

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

java集成paypal ipn响应问题

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

paypal消息通知IPN

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

paypal资料

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

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布局之前&#xff0c;常用布局有&#xff1a;流式布局&#xff0c;浮动布局&#xff0c;定位布局等等。这些布局的缺陷是子元素需要自己控制自己在父元素中的位置&#xff0c;还要注意父元素高度坍塌。 flex布局是一种布局模型&#xff0…

CSS常用布局二(flex布局)

flex布局 前言&#xff1a;flex是flexible box的缩写&#xff0c;译为“弹性布局”&#xff0c;用来为盒模型提供最大的灵活性&#xff0c;任何一个容器都可以指定为flex布局&#xff0c;只需要设置“display:flex"即可&#xff1b;行内元素可以通过设置”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 是什么&#xff1f; flex 是 Flexible Box 的缩写&#xff0c;就是弹性盒子布局的意思 2. 为什么我们需要 flex? 解决元素居中问题 自动弹性伸缩&#xff0c;合适适配不同大小的屏幕&#xff0c;和移动端 3.flex 常见术语 三个2 序号简…

SQL语句的解析过程

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

SQL学习TASK06

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

MySQL高级SQL语句

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

HANA 一些sql语句

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

SQL语句的封装

本篇供个人学习使用&#xff0c;有问题欢迎讨论 封装SQL语句 ​ 在封装SQL语句之前&#xff0c;我们得知道什么是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、主键约束&#xff08;1&#xff09;添加主键约束方式一&#xff1a;创建表时&#xff0c;在字段描述处&#xff0c;声明指定字段为主键方式二&#xff1a;创建表时&#xff0c;在constraint约束区域&#xff0c;声明指定字段为主键方式三&…

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

目录 数据库增删改查SQL语句 MySQL数据库指令 1.查询数据库 2.创建数据库 3.删除数据库 4.选择数据库 创建表table 查看所有表 创建表 查看指定表的结构 删除表 数据库命令进行注释 增删改查&#xff08;CRUD&#xff09;详细说明 增加 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、公司名称、…