关于调用Classic API查询Transaction记录,是使用Paypal的Merchant API,需要在项目的工程导入SDK包。下面是在Maven项目的pom.xml加入代码:
1 <dependency> 2 <groupId>com.paypal.sdk</groupId> 3 <artifactId>merchantsdk</artifactId> 4 <version>2.2.98</version> 5 </dependency>
至于SDK版本,起初采用最新版本的SDK,结果调用getTransactionDetails方法时某些类型的Transaction信息无法获得。但使用Sample的2.2.98版却可以,不知道在哪个版本中对SDK的修改影响所致。
总体来说,调用API方法分为下面几个步骤:
1. 生成PayPalAPIInterfaceServiceService
1 String configFilePath = "sdk_config.properties"; 2 InputStream is = GeneratePaypalInterfaceService.class 3 .getClassLoader().getResourceAsStream(configFilePath); 4 5 service = new PayPalAPIInterfaceServiceService(is);
sdk_config.properties这个文件的设置会在后续章节里讲到,感觉官方的文档有些地方并没有讲清楚。
传入参数可以是File,InputStream,Properties等几种类型,可按照自己的需求灵活使用,这里只是直接将设置文件以InputStream的形式传入。
2. API传入参数
1 TransactionSearchRequestType searchReqType = new TransactionSearchRequestType(); 2 searchReqType.setStartDate(TransactionUtils.convertUTCDate(dateFrom)); 3 searchReqType.setEndDate(TransactionUtils.convertUTCDate(dateTo)); 4 5 TransactionSearchReq searchReq = new TransactionSearchReq(); 6 searchReq.setTransactionSearchRequest(searchReqType);
业务需求上只需要指定查询的时间段即可,这样就只要传入开始日期和终止日期。不过Paypal的日期参数是UTC的日期格式,需要在程序中处理一下。
但存入数据库又要转换成本地时间,所以另外写了两个共通函数专门处理日期转换。
另外的参数还支持传入对方账号,货币种类,特定的transactionId等等,具体参考官方SDK。
3. Call API Method
1 TransactionSearchResponseType searchResp = new TransactionSearchResponseType(); 2 searchResp = service.transactionSearch(searchReq);
根据传入的查询参数,获取的Transaction基本信息都包含在searchResp中,例如TransactionID,交易时间,金额等。
然后根据得到的TransactionID列表,可循环再调用getTransactionDetails方法,传入TransactionID,得到更详细的交易信息。
1 // Get transaction detail 2 GetTransactionDetailsReq getDetailsReq = new GetTransactionDetailsReq(); 3 GetTransactionDetailsRequestType getDetailsReqType = new GetTransactionDetailsRequestType(); 4 5 getDetailsReqType.setTransactionID(id); 6 getDetailsReq.setGetTransactionDetailsRequest(getDetailsReqType); 7 getDetailsResp = service.getTransactionDetails(getDetailsReq);
注意点
transactionSearch方法有一个限制条件,每一次查询最多只能返回100条交易记录,如果有多于100条记录的话就需要另外的思路解决。
当查询成功时,返回的resp.getAck().getValue()等于"Success",但如果多于100条则是"Warning"。
个人采用了递归的方式,可以将日期对拆为两部分再分别查询,用二分法一直到每一部分都少于100条为止。或是将目前查询到的最前一个记录日期作为新的终止日期(因为Paypal查询是从最近的日期开始倒序查询),反复查询一直到成功完成查询。实际项目中使用了后一种方法。
另外,调用这两个方法时,并不是所有的交易类型都能正常取到,个人感觉属于中间过程的某些交易类型就会被API忽略掉。
粗略整理了一下大概有以下这些:
TransactionSearch无法取到的类型--
[Update to Reversal]
[Invoice Sent]
[Update to eCheque Received]
[Payment Review]
getTransactionDetails无法取到的类型--
[Cancelled Fee]
[Withdraw Funds to Bank Account]
Transaction类型配对
Paypal的用户界面上是可以download历史交易记录的,但得到的交易类型和实际API取到的交易类型在名称上又有所区别。
大概的Mapping关系如下:
<Invoice> <API>
[PayPal Express Checkout Payment Received] -> [Payment]
[Mobile Express Checkout Payment Received] -> [Payment]
[Mobile Payment Received] -> [Payment]
[Payment Received] -> [Payment]
[Web Accept Payment Received] -> [Payment]
[Pre-approved Payment Sent] -> [Payment]
[Recurring Payment Sent] -> [Recurring Payment]
[Chargeback Settlement] -> [Transfer]
[Withdraw Funds to Bank Account] -> [Transfer]
[Temporary Hold] -> [Temporary Hold]
[Refund] -> [Refund]
[Refund to XXX] -> [Refund]
[Reversal] -> [Reversal]
[Cancelled Fee] -> [Fee Reversal]
-- 未完待续 --