一、Java支付对接
支付方式:
标准支付主要特点是只需要集成paypal按钮,所有的付款流程由paypal控制,接入方不需要关心支付细节。当用户完成支付后,paypal会通过同步PDT或者异步IPN机制来通知接入方,这种方式比较轻量级,对接难度最小,而且对借入方的入侵较小。
快速支付相对复杂,支付过程由接入方控制,通过调用3个接口来实现。从接入方网页跳转到paypal支付页面前,第一个接口触发,用于向paypal申请支付token。接着用户进入paypal支付页面,并进行支付授权,授权接口中会提交上一步获取的支付token,这个过程由paypal控制,并且没有进行实际支付,接着接入方调用第二个接口,用于获取用户的授权信息,包括支付金额,支付产品等信息,这些基础信息核对无误后,调用第三个接口,进行实际付费扣款,扣款成功后,paypal同样会进行同步PDT和异步IPN通知,这种方式很灵活,控制力强,但编码复杂度较高,入侵性较大。从实际情况考虑,我们选择了采标标准支付方式接入paypal支付。
通知方式:paypal支付的IPN和PDT两种通知方式,IPN异步通知,可能会有时延,但可靠性高,当接入方主机不可达时,有重试机制保证IPN通知尽量抵达接入方服务器。接入方收到IPN通知后,需要对其确认。确认方法为,把接收到的IPN通知原封不动的作为请求体,调用IPN确认接口。PDT通知是是实时的,但可靠性不高,因为只会通知一次,没有重试机制,一旦接入方出现主机不可达,这样的消息将会被丢失。官方推荐,IPN通知和PDT通知最好混合使用,以满足时效性和可靠性的保证。我们采用了IPN和PDT两种通知机制。
Demo 网址:https://demo.paypal.com/c2/demo/home
V1 版本已过期,我们使用V2对接支付
V2文档: https://developer.paypal.com/docs/api/payments/v2/
二、集成paypal的准备
登录开发者中心. https://developer.paypal.com
点击右上角的按钮 “Dashboard”、进入沙箱账号面板
在左边的导航栏中点击 Sandbox 下的 Accounts、创建测试用户
登录沙箱账户、沙箱登录地址: https://www.sandbox.paypal.com 创建应用(sandbox为测试环境/live为真实环境)注 这里登录商家账户进行设置
获取创建应用的clientId 和 clientSecret
应用详情页下方创建PDT通知路径(代码不是使用的pdt通知)
登录沙箱账户设置项目使用的IPN通知的url
基本设置就这些 不多少
下面开始上干货(代码)
引入maven参数
<!--PayPal-->
<dependency>
<groupId>com.paypal.sdk</groupId>
<artifactId>rest-api-sdk</artifactId>
<version>1.4.2</version>
</dependency>
<dependency>
<groupId>com.paypal.sdk</groupId>
<artifactId>checkout-sdk</artifactId>
<version>1.0.2</version>
</dependency>
<!--PayPal-->
yml文件配置paypal信息(email为账户商家邮箱用于检测ipn的通知数据)
编写PayPalClient环境请求配置
package com.szylt.kidsays.project.manager.config.paypal;
import com.paypal.core.PayPalEnvironment;
import com.paypal.core.PayPalHttpClient;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.json.JSONArray;
import org.json.JSONObject;
import java.util.Iterator;
@Slf4j
public class PayPalClient {
public PayPalHttpClient client(String mode, String clientId, String clientSecret) {
log.info("mode={}, clientId={}, clientSecret={}", mode, clientId, clientSecret);
PayPalEnvironment environment = mode.equals("live") ? new PayPalEnvironment.Live(clientId, clientSecret) : new PayPalEnvironment.Sandbox(clientId, clientSecret);
return new PayPalHttpClient(environment);
}
/**
* @param jo
* @param pre
* @return
*/
public String prettyPrint(JSONObject jo, String pre) {
Iterator<?> keys = jo.keys();
StringBuilder pretty = new StringBuilder();
while (keys.hasNext()) {
String key = (String) keys.next();
pretty.append(String.format("%s%s: ", pre, StringUtils.capitalize(key)));
if (jo.get(key) instanceof JSONObject) {
pretty.append(prettyPrint(jo.getJSONObject(key), pre + "\t"));
} else if (jo.get(key) instanceof JSONArray) {
int sno = 1;
for (Object jsonObject : jo.getJSONArray(key)) {
pretty.append(String.format("\n%s\t%d:\n", pre, sno++));
pretty.append(prettyPrint((JSONObject) jsonObject, pre + "\t\t"));
}
} else {
pretty.append(String.format("%s\n", jo.getString(key)));
}
}
return pretty.toString();
}
}
编写paypal的支付配置
package com.szylt.kidsays.project.manager.config.paypal;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* paypal支付配置
*/
@Component
public class PaypalConfig implements InitializingBean {
//统一在application.yml配置文件中
@Value("${paypal.client.mode}")
public String mode;
@Value("${paypal.client.app}")
public String clientId;
@Value("${paypal.client.secret}")
public String clientSecret;
@Value("${paypal.client.email}")
public String email;
public static String MODE ;
public static String CLIENT_ID;
public static String CLIENT_SECRET;
public static String EMAIL;
@Override
public void afterPropertiesSet() throws Exception {
MODE = mode;
CLIENT_ID = clientId;
CLIENT_SECRET = clientSecret;
EMAIL = email;
}
}
编写paypal路径工具类
package com.szylt.kidsays.project.manager.config.util.pal;
import javax.servlet.http.HttpServletRequest;
/**
* 路径工具
*/
public class URLUtils {
public static String getBaseURl(HttpServletRequest request) {
String scheme = request.getScheme();
String serverName = request.getServerName();
int serverPort = request.getServerPort();
String contextPath = request.getContextPath();
StringBuffer url = new StringBuffer();
url.append(scheme).append("://").append(serverName);
if ((serverPort != 80) && (serverPort != 443)) {
url.append(":").append(serverPort);
}
url.append(contextPath);
if(url.toString().endsWith("/")){
url.append("/");
}
return url.toString();
}
}
编写请求支付所需要的PayPalCheckoutConstant常量类
package com.szylt.kidsays.project.manager.config.util.pal;
public class PayPalCheckoutConstant {
public static final String CAPTURE = "CAPTURE";
/**
* PayPal网站上PayPal帐户中的公司名称
*/
public static final String BRAND_NAME = "自定义名称";
/**
* PayPal网站上商品名称
*/
public static final String DESCRIPTION = "自定义名称";
/**
* 交易成功
*/
public static final String SUCCESS = "success";
/**
* ipn回调,付款因退款或其他类型的冲销而被冲销。资金已从您的帐户余额中删除,并退还给买方
*/
public static final String PAYMENT_STATUS_REVERSED = "Reversed";
/**
* ipn回调, 撤销已被取消。例如,您赢得了与客户的纠纷,并且撤回的交易资金已退还给您
*/
public static final String PAYMENT_STATUS_CANCELED_REVERSAL = "Canceled_Reversal";
/**
* ipn回调,付款被拒绝
*/
public static final String PAYMENT_STATUS_DENIED = "Denied";
/**
* ipn回调, 此授权已过期,无法捕获
*/
public static final String PAYMENT_STATUS_EXPIRED = "Expired";
/**
* ipn回调, 德国的ELV付款是通过Express Checkout进行的
*/
public static final String PAYMENT_STATUS_CREATED = "Created";
/**
* ipn回调, 付款失败。仅当付款是通过您客户的银行帐户进行的。
*/
public static final String PAYMENT_STATUS_FAILED = "Failed";
/**
* ipn回调,付款已被接受
*/
public static final String PAYMENT_STATUS_PROCESSED = "Processed";
/**
* ipn回调,此授权已失效
*/
public static final String PAYMENT_STATUS_VOIDED = "Voided";
}
编写paypal订单创建类CreateOrder(生成paypal订单 不是本地订单)
package com.szylt.kidsays.project.manager.config.util.pal.operation;
import com.paypal.http.HttpResponse;
import com.paypal.orders.*;
import com.szylt.kidsays.project.manager.config.paypal.PayPalClient;
import com.szylt.kidsays.project.manager.config.paypal.PaypalConfig;
import com.szylt.kidsays.project.manager.config.util.pal.PayPalCheckoutConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@Slf4j
@Component
public class CreateOrder {
/**
* 生成订单主体信息
*/
private OrderRequest buildRequestBody(String cancelUrl,String returnUrl,String customId,String invoiceId,
String currencyCode,String value) {
OrderRequest orderRequest = new OrderRequest();
orderRequest.checkoutPaymentIntent(PayPalCheckoutConstant.CAPTURE);
ApplicationContext applicationContext = new ApplicationContext()
.brandName(PayPalCheckoutConstant.BRAND_NAME)
.cancelUrl(cancelUrl).returnUrl(returnUrl);
orderRequest.applicationContext(applicationContext);
List<PurchaseUnitRequest> purchaseUnits = new ArrayList<>();
purchaseUnits
.add(new PurchaseUnitRequest()
.description(PayPalCheckoutConstant.DESCRIPTION)
.customId(customId) // 自定义编号 这里我放入的也是 本地订单号
.invoiceId(invoiceId) // 本地订单号
.amountWithBreakdown(new AmountWithBreakdown()
.currencyCode(currencyCode)
.value(String.valueOf(value))
));
orderRequest.purchaseUnits(purchaseUnits);
return orderRequest;
}
/**
* 创建订单的方法
* @throws //收银台地址
*/
public String createOrder(String cancelUrl,String returnUrl,String customId,String invoiceId,
String currencyCode,String value) throws IOException {
OrdersCreateRequest request = new OrdersCreateRequest();
request.header("prefer","return=representation");
request.requestBody(buildRequestBody( cancelUrl, returnUrl, customId, invoiceId,
currencyCode, value));
PayPalClient payPalClient = new PayPalClient();
HttpResponse<Order> response = null;
try {
response = payPalClient.client(PaypalConfig.MODE, PaypalConfig.CLIENT_ID,PaypalConfig.CLIENT_SECRET).execute(request);
} catch (IOException e1) {
try {
log.error("第1次调用paypal订单创建失败");
response = payPalClient.client(PaypalConfig.MODE, PaypalConfig.CLIENT_ID,PaypalConfig.CLIENT_SECRET).execute(request);
} catch (Exception e) {
try {
log.error("第2次调用paypal订单创建失败");
response = payPalClient.client(PaypalConfig.MODE, PaypalConfig.CLIENT_ID,PaypalConfig.CLIENT_SECRET).execute(request);
} catch (Exception e2) {
log.error("第3次调用paypal订单创建失败,失败原因:{}", e2.getMessage());
}
}
}
String approve = "";
if (response.statusCode() == 201) {
log.info("Status Code = {}, Status = {}, OrderID = {}, Intent = {}", response.statusCode(), response.result().status(), response.result().id(), response.result().checkoutPaymentIntent());
Order order = response.result();
order.links().forEach(link -> log.info(link.rel() + " => " + link.method() + ":" + link.href()));
//交易成功后,跳转反馈地址
for(LinkDescription links : order.links()){
if(links.rel().equals("approve")){
approve = links.href();
}
}
}
return approve;
}
}
编写paypal订单捕获类用于从用户账户扣款操作CaptureOrder
package com.szylt.kidsays.project.manager.config.util.pal.operation;
import com.paypal.http.HttpResponse;
import com.paypal.orders.*;
import com.paypal.payments.CapturesGetRequest;
import com.szylt.kidsays.project.manager.config.paypal.PayPalClient;
import com.szylt.kidsays.project.manager.config.paypal.PaypalConfig;
import com.szylt.kidsays.project.vo.paypal.PaypalVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.io.IOException;
@Slf4j
@Component
public class CaptureOrder extends PayPalClient {
public OrderRequest buildRequestBody() {
return new OrderRequest();
}
/**
* 用户授权支付成功,进行扣款操作
*/
public PaypalVo captureOrder(String orderId) throws IOException {
PaypalVo paypalVo = new PaypalVo();
OrdersCaptureRequest request = new OrdersCaptureRequest(orderId);
request.requestBody(new OrderRequest());
PayPalClient payPalClient = new PayPalClient();
HttpResponse<Order> response = null;
try {
response = payPalClient.client(PaypalConfig.MODE, PaypalConfig.CLIENT_ID, PaypalConfig.CLIENT_SECRET).execute(request);
} catch (IOException e1) {
try {
log.error("第1次调用paypal扣款失败");
response = payPalClient.client(PaypalConfig.MODE, PaypalConfig.CLIENT_ID, PaypalConfig.CLIENT_SECRET).execute(request);
} catch (Exception e) {
try {
log.error("第2次调用paypal扣款失败");
response = payPalClient.client(PaypalConfig.MODE, PaypalConfig.CLIENT_ID, PaypalConfig.CLIENT_SECRET).execute(request);
} catch (Exception e2) {
log.error("第3次调用paypal扣款失败,失败原因 {}", e2.getMessage() );
}
}
}
for (PurchaseUnit purchaseUnit : response.result().purchaseUnits()) {
for (Capture capture : purchaseUnit.payments().captures()) {
log.info("Capture id: {}", capture.id());
log.info("status: {}", capture.status());
log.info("invoice_id: {}", capture.invoiceId());
//paypal交易号
log.info("paypal交易号" + capture.id());
//商户订单号,之前生成的带用户ID的订单号
log.info(capture.invoiceId());
paypalVo.setOId(capture.invoiceId());
paypalVo.setCaptureId(capture.id());
if("COMPLETED".equals(capture.status())) {
paypalVo.setIsPaySuccess("SUCCESS");
} else if("PENDING".equals(capture.status())) {
log.info("status_details: {}", capture.captureStatusDetails().reason());
String reason = "PENDING";
if(capture.captureStatusDetails() != null && capture.captureStatusDetails().reason() != null) {
reason = capture.captureStatusDetails().reason();
}
// 支付成功,状态为=PENDING
log.info("支付成功,状态为=PENDING : {}", reason);
paypalVo.setIsPaySuccess("PENDING");
}else {
paypalVo.setIsPaySuccess("FAILURE");
}
}
}
return paypalVo;
}
/**
* 支付后查询扣款信息
*/
public Boolean getCapture(String captureId) {
// 扣款查询
CapturesGetRequest restRequest = new CapturesGetRequest(captureId);
PayPalClient payPalClient = new PayPalClient();
HttpResponse<com.paypal.payments.Capture> response = null;
try {
response = payPalClient.client(PaypalConfig.MODE, PaypalConfig.CLIENT_ID, PaypalConfig.CLIENT_SECRET).execute(restRequest);
} catch (IOException e) {
log.info("查询支付扣款失败:{}",e.getMessage());
return false;
}
log.info("Capture ids: " + response.result().id());
return true;
}
}
PaypalVo自定义的支付返回类
package com.szylt.kidsays.project.vo.paypal;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel("paypal支付结果返回模型")
public class PaypalVo {
/**
* 捕获id 第三方id
*/
@ApiModelProperty("捕获id 第三方id")
private String captureId;
/**
* 是否支付成功(SUCCESS/PENDING/FAILURE)
*/
@ApiModelProperty("是否支付成功(SUCCESS/PENDING/FAILURE)")
private String isPaySuccess;
/**
* 本地订单号
*/
@ApiModelProperty("本地订单号")
private String oId;
}
现在开始编写 service吧
package com.szylt.kidsays.project.manager.paypal;
import com.paypal.base.rest.PayPalRESTException;
import com.szylt.kidsays.project.vo.paypal.PaypalVo;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
/**
* paypal支付接口
*/
public interface PaypalService {
/**
* 创建支付
* @param request
* @param oId 本地订单单号
* @return
*/
String createPayment(HttpServletRequest request,String oId);
/**
* 执行支付
* @param token paypal支付编号id 唯一
* @param payerID
* @return
* @throws
*/
PaypalVo successPay(String token, String payerID) throws PayPalRESTException;
/**
* 回调
* @param map
*/
String callback(@SuppressWarnings("rawtypes") Map map);
}
回调数据的转换放在还后面
实现server定义的接口
package com.szylt.kidsays.project.manager.paypal.impl;
import com.paypal.base.rest.PayPalRESTException;
import com.szylt.kidsays.project.entity.HOrder;
import com.szylt.kidsays.project.manager.config.paypal.PaypalConfig;
import com.szylt.kidsays.project.manager.config.util.pal.PayPalCheckoutConstant;
import com.szylt.kidsays.project.manager.config.util.pal.URLUtils;
import com.szylt.kidsays.project.manager.config.util.pal.operation.CaptureOrder;
import com.szylt.kidsays.project.manager.config.util.pal.operation.CreateOrder;
import com.szylt.kidsays.project.mapper.HOrderMapper;
import com.szylt.kidsays.project.manager.paypal.PaypalService;
import com.szylt.kidsays.project.service.IHOrderService;
import com.szylt.kidsays.project.vo.paypal.PaypalVo;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Map;
/**
* paypal支付接口实现
*/
@Service
@Slf4j
@AllArgsConstructor
public class PaypalServiceImpl implements PaypalService {
private CreateOrder createOrder;
private HOrderMapper orderMapper;
private CaptureOrder captureOrder;
private IHOrderService orderService;
public static final String RETURN_URL = "paypal/return_url";
public static final String CANCEL_URL = "paypal/cancel_url";
/**
* 创建支付
* @param request
* @param oId 本地订单单号
* @return
*/
@Override
public String createPayment(HttpServletRequest request,String oId) {
HOrder sOrder = orderMapper.findOrder(oId); // 本地订单数据
String cancelUrl = URLUtils.getBaseURl(request) + "/" + CANCEL_URL; // 支付取消返回链接
String returnUrl = URLUtils.getBaseURl(request) + "/" + RETURN_URL; // 支付成功返回链接
String approve = "";
try {
approve = createOrder.createOrder(cancelUrl,returnUrl,sOrder.getOId(),sOrder.getOId(),"USD",String.valueOf(sOrder.getOrderPriceUsd()));
} catch (IOException e) {
e.printStackTrace();
}
return "redirect:" + approve;
}
/**
* 执行支付 捕获订单进行扣款操作
* @param token paypal支付编号id 唯一
* @param payerID
* @return
* @throws
*/
@Override
public PaypalVo successPay(String token, String payerID) throws PayPalRESTException {
PaypalVo result = null;
try {
result = captureOrder.captureOrder(token);
captureOrder.getCapture(result.getCaptureId());
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
/**
* 回调
* @param map
*/
@Override
public String callback(@SuppressWarnings("rawtypes") Map map) {
log.info(map.toString());
String outTradeNo = (String)map.get("invoice");
String paymentStatus = (String)map.get("payment_status");
String amount = (String)map.get("mc_gross");
String currency = (String)map.get("mc_currency");
String paymentId = (String)map.get("txn_id");
String parentPaymentId = (String)map.get("parent_txn_id");
log.info("商家订单号 = {}", outTradeNo);
log.info("订单状态 = {}", paymentStatus);
log.info("金额 = {}", amount);
log.info("币种 = {}", currency);
log.info("流水号 = {}", paymentId);
log.info("父流水号 = {}", parentPaymentId);
if (!PaypalConfig.EMAIL.equals((String) map.get("receiver_email"))) {
log.info("FAIL = 商户id错误, outTradeNo = {}", outTradeNo);
return "failure";
}
if("Completed".equals(paymentStatus)) {
//进行数据库操作
boolean result = orderService.updateOrder(outTradeNo,paymentId,"paypal支付",1);
//
log.info("支付成功,状态为=COMPLETED");
return PayPalCheckoutConstant.SUCCESS;
}
// //退款操作不开放
// if("Refunded".equals(paymentStatus)) {
// //进行数据库操作
// log.info("退款成功");
// return PayPalCheckoutConstant.SUCCESS;
// }
if("Pending".equals(paymentStatus) && StringUtils.isEmpty(parentPaymentId)) {
String pendingReason = String.valueOf(map.get("pending_reason"));
//进行数据库操作
log.info("订单支付成功,状态为=PENDING,产生此状态的原因是 {}", pendingReason );
return PayPalCheckoutConstant.SUCCESS;
}
if(StringUtils.isEmpty(parentPaymentId)) {
if(PayPalCheckoutConstant.PAYMENT_STATUS_REVERSED.equals(paymentStatus)
|| PayPalCheckoutConstant.PAYMENT_STATUS_CANCELED_REVERSAL.equals(paymentStatus)
|| PayPalCheckoutConstant.PAYMENT_STATUS_DENIED.equals(paymentStatus)) {
String reasonCode = String.valueOf(map.get("reason_code"));
//进行数据库操作(状态修改)
log.info("订单异常,请尽快查看处理,状态为={},产生此状态的原因是 {} ", paymentStatus, reasonCode);
return PayPalCheckoutConstant.SUCCESS;
}
if(PayPalCheckoutConstant.PAYMENT_STATUS_EXPIRED.equals(paymentStatus)
|| PayPalCheckoutConstant.PAYMENT_STATUS_CREATED.equals(paymentStatus)
|| PayPalCheckoutConstant.PAYMENT_STATUS_FAILED.equals(paymentStatus)
|| PayPalCheckoutConstant.PAYMENT_STATUS_PROCESSED.equals(paymentStatus)
|| PayPalCheckoutConstant.PAYMENT_STATUS_VOIDED.equals(paymentStatus)) {
//进行数据库操作(状态修改)
log.info("其他订单状态,订单异常,请尽快查看处理, 状态={}", paymentStatus);
return PayPalCheckoutConstant.SUCCESS;
}
}
return "failure";
}
}
编写PaypalController
package com.szylt.kidsays.project.manager.controller;
import com.paypal.base.rest.PayPalRESTException;
import com.szylt.kidsays.project.manager.config.util.pal.RequestToMapUtil;
import com.szylt.kidsays.project.manager.paypal.PaypalService;
import com.szylt.kidsays.project.vo.paypal.PaypalVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* paypal支付前端控制器
*/
@Slf4j
@Api(tags = "paypal支付")
@Controller
@AllArgsConstructor
@RequestMapping("/paypal")
public class PaypalController {
private PaypalService paypalService;
/**
* 创建支付
* @param request
* @return
*/
@ApiOperation("创建支付")
@GetMapping( value = "/create_payment")
public String payment(HttpServletRequest request,String oId) {
return paypalService.createPayment(request,oId);
}
/**
* 执行支付
* @param token
* @param PayerID
* @return
* @throws PayPalRESTException
*/
@ApiOperation("执行支付")
@GetMapping(value ="/return_url" )
public String successPay(@RequestParam("token") String token, @RequestParam("PayerID") String PayerID){
try {
PaypalVo result = paypalService.successPay(token,PayerID);
if("SUCCESS".equals(result.getIsPaySuccess())){
return "redirect:/pay/list";
}
} catch (PayPalRESTException e) {
e.printStackTrace();
}
return "redirect:/";
}
/**
* ipn异步回调
* @param request
* @param response
* @return
*/
@ApiOperation(value = "ipn异步回调") //https://e4726dc5b647.ngrok.io/api/paypal/call/back
@ResponseBody
@PostMapping(value = "/call/back")
public String callback(HttpServletRequest request, HttpServletResponse response) {
return paypalService.callback(RequestToMapUtil.getParameterMap(request));
}
}
处理ipn异步回调的Request转换为map
数据
package com.szylt.kidsays.project.manager.config.util.pal;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RequestToMapUtil {
@SuppressWarnings({ "unchecked", "rawtypes" })
public static Map getParameterMap(HttpServletRequest request) {
// 参数Map
Map properties = request.getParameterMap();
// 返回值Map
Map returnMap = new HashMap();
Iterator entries = properties.entrySet().iterator();
Map.Entry entry;
String name = "";
String value = "";
while (entries.hasNext()) {
entry = (Map.Entry) entries.next();
name = (String) entry.getKey();
Object valueObj = entry.getValue();
if (null == valueObj) {
value = "";
} else if (valueObj instanceof String[]) {
String[] values = (String[]) valueObj;
for (int i = 0; i < values.length; i++) {
value = values[i] + ",";
}
value = value.substring(0, value.length() - 1);
} else {
value = valueObj.toString();
}
returnMap.put(name, value);
}
return returnMap;
}
public static Map<String, Object> getPrepayMapInfo(String Str) {
String notityXml = Str.replaceAll("</?xml>", "");
Pattern pattern = Pattern.compile("<.*?/.*?>");
Matcher matcher = pattern.matcher(notityXml);
Pattern pattern2 = Pattern.compile("!.*]");
Map<String, Object> mapInfo = new HashMap<>();
while (matcher.find()) {
String key = matcher.group().replaceAll(".*/", "");
key = key.substring(0, key.length() - 1);
Matcher matcher2 = pattern2.matcher(matcher.group());
String value = matcher.group().replaceAll("</?.*?>", "");
if (matcher2.find() && !value.equals("DATA")) {
value = matcher2.group().replaceAll("!.*\\[", "");
value = value.substring(0, value.length() - 2);
}
mapInfo.put(key, value);
}
return mapInfo;
}
}
一个paypal的支付就这样完成了
具体操作请集合公司业务情况操作
如果是是有按钮支付的请交给前端处理 后端结束通知修改数据库就可以了