Browse Source

paypal支付

lyhzzz 2 years ago
parent
commit
3ad1e77bf6

+ 5 - 0
src/main/java/com/fdkankan/pay/common/ResultCode.java

@@ -3,12 +3,17 @@ package com.fdkankan.pay.common;
 
 public enum ResultCode {
     SYSTEM_ERROR(500, "系统异常"),
+
     DATA_TOO_LONG(10001, "长度超出限制!"),
     WX_CONFIG_NOT(10002, "微信config缺失!"),
     WX_ORDER_PAY_TYPE_ERROR(10003, "微信支付类型错误!"),
     PARAM_ERROR(10004, "参数缺失!"),
+
     ORDER_NOT_EXIST(10005, "订单不存在!"),
     ALIPAY_ERROR(10006, "获取支付宝扫码链接失败!"),
+    ALIPAY_CONFIG_ERROR(10007, "支付宝config缺失!"),
+    PAYPAL_ERROR(10008, "paypal支付失败!"),
+    PAYPAL_CONFIG_ERROR(10009, "paypal-config缺失!"),
 
     ;
 

+ 21 - 0
src/main/java/com/fdkankan/pay/controller/PaypalConfigController.java

@@ -0,0 +1,21 @@
+package com.fdkankan.pay.controller;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author 
+ * @since 2023-04-18
+ */
+@RestController
+@RequestMapping("/pay/paypalConfig")
+public class PaypalConfigController {
+
+}
+

+ 69 - 0
src/main/java/com/fdkankan/pay/entity/PaypalConfig.java

@@ -0,0 +1,69 @@
+package com.fdkankan.pay.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.io.Serializable;
+import java.util.Date;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author 
+ * @since 2023-04-18
+ */
+@Getter
+@Setter
+@TableName("t_paypal_config")
+public class PaypalConfig implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * paypal支付
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 客户端id
+     */
+    @TableField("client_id")
+    private String clientId;
+
+    /**
+     * 密钥
+     */
+    @TableField("secret")
+    private String secret;
+
+    @TableField("mode")
+    private String mode;
+
+    @TableField("call_back_url")
+    private String callBackUrl;
+
+    @TableField("serve_id")
+    private Integer serveId;
+
+    @TableField("currency")
+    private String currency;
+
+    @TableField("rec_status")
+    @TableLogic(value = "A",delval = "I")
+    private String recStatus;
+
+    @TableField("create_time")
+    private Date createTime;
+
+    @TableField("update_time")
+    private Date updateTime;
+
+
+}

+ 1 - 1
src/main/java/com/fdkankan/pay/generate/AutoGenerate.java

@@ -18,7 +18,7 @@ public class AutoGenerate {
         String path =System.getProperty("user.dir");
 
         generate(path,"pay", getTables(new String[]{
-                "t_ali_config"
+                "t_paypal_config"
         }));
 
 //        generate(path,"goods", getTables(new String[]{

+ 18 - 0
src/main/java/com/fdkankan/pay/mapper/IPaypalConfigMapper.java

@@ -0,0 +1,18 @@
+package com.fdkankan.pay.mapper;
+
+import com.fdkankan.pay.entity.PaypalConfig;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author 
+ * @since 2023-04-18
+ */
+@Mapper
+public interface IPaypalConfigMapper extends BaseMapper<PaypalConfig> {
+
+}

+ 17 - 0
src/main/java/com/fdkankan/pay/service/IPaypalConfigService.java

@@ -0,0 +1,17 @@
+package com.fdkankan.pay.service;
+
+import com.fdkankan.pay.entity.PaypalConfig;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author 
+ * @since 2023-04-18
+ */
+public interface IPaypalConfigService extends IService<PaypalConfig> {
+
+    PaypalConfig getByServeId(Integer serveId);
+}

+ 27 - 0
src/main/java/com/fdkankan/pay/service/impl/PaypalConfigServiceImpl.java

@@ -0,0 +1,27 @@
+package com.fdkankan.pay.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.fdkankan.pay.entity.PaypalConfig;
+import com.fdkankan.pay.mapper.IPaypalConfigMapper;
+import com.fdkankan.pay.service.IPaypalConfigService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author 
+ * @since 2023-04-18
+ */
+@Service
+public class PaypalConfigServiceImpl extends ServiceImpl<IPaypalConfigMapper, PaypalConfig> implements IPaypalConfigService {
+
+    @Override
+    public PaypalConfig getByServeId(Integer serveId) {
+        LambdaQueryWrapper<PaypalConfig> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(PaypalConfig::getServeId,serveId);
+        return this.getOne(wrapper);
+    }
+}

+ 1 - 1
src/main/java/com/fdkankan/pay/util/alipay/sdk/AlipayService.java

@@ -58,7 +58,7 @@ public class AlipayService {
         String subject = param.getOrderType();
         AliConfig aliConfig = aliConfigService.getByServeId(param.getServeId());
         if(aliConfig == null){
-            throw new BusinessException(ResultCode.WX_CONFIG_NOT);
+            throw new BusinessException(ResultCode.ALIPAY_CONFIG_ERROR);
         }
         aliConfig.setCallBackUrl( CacheUtil.mainUrl + aliConfig.getCallBackUrl() + "/" + orderSn);
         String body = subject;

+ 130 - 0
src/main/java/com/fdkankan/pay/util/paypal/sdk/PayPalmentEx.java

@@ -0,0 +1,130 @@
+package com.fdkankan.pay.util.paypal.sdk;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.List;
+
+public class PayPalmentEx implements Serializable {
+
+    private static final long serialVersionUID = 5027458587257867876L;
+    /**
+     * 订单Id
+     */
+    private String orderSn;
+    /**
+     * 支付的总价
+     */
+    private BigDecimal orderTotal;
+    /**
+     * 商品总价
+     */
+    private BigDecimal subTotal;
+    /**
+     * 税费
+     */
+    private BigDecimal tax;
+    /**
+     * 描述
+     */
+    private String description;
+    /**
+     * 成功回调url
+     */
+    private String successUrl;
+    /**
+     * 支付失败url
+     */
+    private String failUrl;
+    /**
+     * 取消支付url
+     */
+    private String cancelUrl;
+    /**
+     * 收货地址
+     */
+    private PaypalOrderAddressEx paypayOrderAddressEx;
+    /**
+     * 订单商品明细
+     */
+    private List<PaypalOrderItemEx> paypalOrderItemExList;
+
+    public String getOrderSn() {
+        return orderSn;
+    }
+
+    public void setOrderSn(String orderSn) {
+        this.orderSn = orderSn;
+    }
+
+    public BigDecimal getOrderTotal() {
+        return orderTotal;
+    }
+
+    public void setOrderTotal(BigDecimal orderTotal) {
+        this.orderTotal = orderTotal;
+    }
+
+    public BigDecimal getSubTotal() {
+        return subTotal;
+    }
+
+    public void setSubTotal(BigDecimal subTotal) {
+        this.subTotal = subTotal;
+    }
+
+    public BigDecimal getTax() {
+        return tax;
+    }
+
+    public void setTax(BigDecimal tax) {
+        this.tax = tax;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public String getSuccessUrl() {
+        return successUrl;
+    }
+
+    public void setSuccessUrl(String successUrl) {
+        this.successUrl = successUrl;
+    }
+
+    public String getFailUrl() {
+        return failUrl;
+    }
+
+    public void setFailUrl(String failUrl) {
+        this.failUrl = failUrl;
+    }
+
+    public String getCancelUrl() {
+        return cancelUrl;
+    }
+
+    public void setCancelUrl(String cancelUrl) {
+        this.cancelUrl = cancelUrl;
+    }
+
+    public PaypalOrderAddressEx getPaypayOrderAddressEx() {
+        return paypayOrderAddressEx;
+    }
+
+    public void setPaypayOrderAddressEx(PaypalOrderAddressEx paypayOrderAddressEx) {
+        this.paypayOrderAddressEx = paypayOrderAddressEx;
+    }
+
+    public List<PaypalOrderItemEx> getPaypalOrderItemExList() {
+        return paypalOrderItemExList;
+    }
+
+    public void setPaypalOrderItemExList(List<PaypalOrderItemEx> paypalOrderItemExList) {
+        this.paypalOrderItemExList = paypalOrderItemExList;
+    }
+}

+ 88 - 0
src/main/java/com/fdkankan/pay/util/paypal/sdk/PaypalOrderAddressEx.java

@@ -0,0 +1,88 @@
+package com.fdkankan.pay.util.paypal.sdk;
+
+import java.io.Serializable;
+
+public class PaypalOrderAddressEx implements Serializable {
+
+    private static final long serialVersionUID = 5667747195118555705L;
+
+    private String firstName;
+
+    private String lastName;
+
+    private String countryCode;
+
+    private String state;
+
+    private String city;
+
+    private String address;
+
+    private String phone;
+
+    private String postalCode;
+
+    public String getFirstName() {
+        return firstName;
+    }
+
+    public void setFirstName(String firstName) {
+        this.firstName = firstName;
+    }
+
+    public String getLastName() {
+        return lastName;
+    }
+
+    public void setLastName(String lastName) {
+        this.lastName = lastName;
+    }
+
+    public String getCountryCode() {
+        return countryCode;
+    }
+
+    public void setCountryCode(String countryCode) {
+        this.countryCode = countryCode;
+    }
+
+    public String getState() {
+        return state;
+    }
+
+    public void setState(String state) {
+        this.state = state;
+    }
+
+    public String getCity() {
+        return city;
+    }
+
+    public void setCity(String city) {
+        this.city = city;
+    }
+
+    public String getAddress() {
+        return address;
+    }
+
+    public void setAddress(String address) {
+        this.address = address;
+    }
+
+    public String getPhone() {
+        return phone;
+    }
+
+    public void setPhone(String phone) {
+        this.phone = phone;
+    }
+
+    public String getPostalCode() {
+        return postalCode;
+    }
+
+    public void setPostalCode(String postalCode) {
+        this.postalCode = postalCode;
+    }
+}

+ 59 - 0
src/main/java/com/fdkankan/pay/util/paypal/sdk/PaypalOrderItemEx.java

@@ -0,0 +1,59 @@
+package com.fdkankan.pay.util.paypal.sdk;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+public class PaypalOrderItemEx implements Serializable {
+
+    private static final long serialVersionUID = 7764234386178614511L;
+
+    private String sku;
+
+    private String name;
+
+    private BigDecimal price;
+
+    private int quantity;
+
+    private String currency;
+
+    public String getSku() {
+        return sku;
+    }
+
+    public void setSku(String sku) {
+        this.sku = sku;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public BigDecimal getPrice() {
+        return price;
+    }
+
+    public void setPrice(BigDecimal price) {
+        this.price = price;
+    }
+
+    public int getQuantity() {
+        return quantity;
+    }
+
+    public void setQuantity(int quantity) {
+        this.quantity = quantity;
+    }
+
+    public String getCurrency() {
+        return currency;
+    }
+
+    public void setCurrency(String currency) {
+        this.currency = currency;
+    }
+}

+ 5 - 0
src/main/java/com/fdkankan/pay/util/paypal/sdk/PaypalPaymentIntent.java

@@ -0,0 +1,5 @@
+package com.fdkankan.pay.util.paypal.sdk;
+
+public enum PaypalPaymentIntent {
+	sale, authorize, order
+}

+ 5 - 0
src/main/java/com/fdkankan/pay/util/paypal/sdk/PaypalPaymentMethod.java

@@ -0,0 +1,5 @@
+package com.fdkankan.pay.util.paypal.sdk;
+
+public enum PaypalPaymentMethod {
+	credit_card, paypal
+}

+ 318 - 0
src/main/java/com/fdkankan/pay/util/paypal/sdk/PaypalService.java

@@ -0,0 +1,318 @@
+package com.fdkankan.pay.util.paypal.sdk;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.pay.common.ResultCode;
+import com.fdkankan.pay.entity.Order;
+import com.fdkankan.pay.entity.PaypalConfig;
+import com.fdkankan.pay.entity.WxConfig;
+import com.fdkankan.pay.exception.BusinessException;
+import com.fdkankan.pay.service.IPaypalConfigService;
+import com.fdkankan.pay.util.CacheUtil;
+import com.fdkankan.pay.util.UrlUtils;
+import com.paypal.api.payments.*;
+import com.paypal.base.codec.binary.Base64;
+import com.paypal.base.rest.APIContext;
+import com.paypal.base.rest.PayPalRESTException;
+import lombok.extern.log4j.Log4j2;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.math.BigDecimal;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Log4j2
+@Service
+public class PaypalService {
+
+    @Autowired
+    IPaypalConfigService paypalConfigService;
+
+    public Object openPay(Order param, String ip) throws Exception {
+
+        String orderSn = param.getOrderSn();
+        BigDecimal amount = param.getOrderMoney();
+        String subject = param.getOrderType();
+        PaypalConfig paypalConfig = paypalConfigService.getByServeId(param.getServeId());
+        if(paypalConfig == null){
+            throw new BusinessException(ResultCode.PAYPAL_CONFIG_ERROR);
+        }
+        paypalConfig.setCallBackUrl( CacheUtil.mainUrl + paypalConfig.getCallBackUrl() +"/"+orderSn);
+        String body = subject;
+        //paypal支付
+        if(param.getPayType() == 5){
+            return this.payPalPay(orderSn, body, amount,paypalConfig);
+        }
+        throw new BusinessException(ResultCode.WX_ORDER_PAY_TYPE_ERROR);
+    }
+
+
+
+    public JSONObject payPalPay(String orderSn, String body, BigDecimal totalFee,  PaypalConfig paypalConfig) throws Exception {
+        PayPalmentEx payPalmentEx = new PayPalmentEx();
+        payPalmentEx.setOrderSn(orderSn);
+        payPalmentEx.setOrderTotal(totalFee);
+        payPalmentEx.setSubTotal(totalFee);
+        payPalmentEx.setDescription(body);
+
+        Payment payment = this.createPayment(payPalmentEx,paypalConfig);
+        for(Links links : payment.getLinks()){
+            if(links.getRel().equals("approval_url")){
+                // 客户付款登陆地址
+                JSONObject j = new JSONObject();
+                j.put("redirect", links.getHref());
+                j.put("price", totalFee);
+                return j;
+            }
+        }
+        throw new BusinessException(ResultCode.PAYPAL_ERROR);
+    }
+
+
+
+    /**
+     * 创建支付
+     *
+     * @param paymentEx
+     * @return
+     * @throws PayPalRESTException
+     */
+    @Transactional(rollbackFor = Exception.class)
+    public Payment createPayment(PayPalmentEx paymentEx, PaypalConfig paypalConfig) throws PayPalRESTException {
+        Transaction transaction = new Transaction();
+        transaction.setDescription(paymentEx.getDescription());
+        // 将我们的订单ID保存到支付信息中,用于后面支付回传
+        if (null != paymentEx.getOrderSn()) {
+            transaction.setCustom(paymentEx.getOrderSn());
+        }
+        //订单价格
+        Amount amount = new Amount();
+        amount.setCurrency(paypalConfig.getCurrency());
+        // 支付的总价,paypal会校验 total = subTotal + tax + ...
+        amount.setTotal(paymentEx.getOrderTotal().toString());
+        // 设置各种费用
+        Details details = new Details();
+        // 商品总价
+        if (paymentEx.getSubTotal() != null) {
+            details.setSubtotal(paymentEx.getSubTotal().toString());
+        }
+        // 税费
+        if (paymentEx.getTax() != null) {
+            details.setTax(paymentEx.getTax().toString());
+        }
+
+        amount.setDetails(details);
+
+        transaction.setAmount(amount);
+
+        ItemList itemList = new ItemList();
+        // 收货地址
+        PaypalOrderAddressEx orderAddress = paymentEx.getPaypayOrderAddressEx();
+        if (orderAddress != null) {
+            ShippingAddress shippingAddress = new ShippingAddress();
+            if (StringUtils.isNotEmpty(orderAddress.getFirstName()) && StringUtils.isNotEmpty(orderAddress.getLastName())) {
+                shippingAddress.setRecipientName(orderAddress.getFirstName() + "." + orderAddress.getLastName());
+            }
+            shippingAddress.setCountryCode(orderAddress.getCountryCode());
+            shippingAddress.setState(orderAddress.getState());
+            shippingAddress.setCity(orderAddress.getCity());
+            shippingAddress.setLine1(orderAddress.getAddress());
+            shippingAddress.setPhone(orderAddress.getPhone());
+            shippingAddress.setPostalCode(orderAddress.getPostalCode());
+
+            itemList.setShippingAddress(shippingAddress);
+            itemList.setShippingPhoneNumber(orderAddress.getPhone());
+        }
+
+        // 商品明细
+        List<PaypalOrderItemEx> orderItemList = paymentEx.getPaypalOrderItemExList();
+        if (orderItemList != null && orderItemList.size() > 0) {
+            List<Item> items = new ArrayList<>();
+            for (PaypalOrderItemEx orderItemEx : orderItemList) {
+                Item item = new Item();
+                item.setSku(orderItemEx.getSku());
+                item.setName(orderItemEx.getName());
+                item.setPrice(orderItemEx.getPrice().toString());
+                item.setQuantity(String.valueOf(orderItemEx.getQuantity()));
+                item.setCurrency(paypalConfig.getCurrency());
+                items.add(item);
+            }
+            itemList.setItems(items);
+            transaction.setItemList(itemList);
+        }
+
+        List<Transaction> transactions = new ArrayList<>();
+        transactions.add(transaction);
+
+        // 支付信息
+        Payer payer = new Payer();
+        payer.setPaymentMethod(PaypalPaymentMethod.paypal.toString());
+
+        Payment payment = new Payment();
+        //刷新accessToken时间;
+        APIContext apiContext = new APIContext("Bearer " + getAccessToken(paypalConfig));
+        Map<String, String> sdkConfig = new HashMap<>();
+        sdkConfig.put("mode", paypalConfig.getMode());
+        apiContext.setConfigurationMap(sdkConfig);
+
+        payment.setIntent(PaypalPaymentIntent.sale.toString());
+        payment.setPayer(payer);
+        payment.setTransactions(transactions);
+
+        //回调地址
+        RedirectUrls redirectUrls = new RedirectUrls();
+        redirectUrls.setReturnUrl(paypalConfig.getCallBackUrl());
+        redirectUrls.setCancelUrl(paypalConfig.getCallBackUrl());
+        payment.setRedirectUrls(redirectUrls);
+
+        return payment.create(apiContext);
+    }
+
+    /**
+     * 执行支付
+     *
+     * @param paymentId
+     * @param payerId
+     * @return
+     * @throws PayPalRESTException
+     */
+    public Payment executePayment(String paymentId, String payerId,PaypalConfig paypalConfig) throws PayPalRESTException {
+        Payment payment = new Payment();
+        payment.setId(paymentId);
+        PaymentExecution paymentExecute = new PaymentExecution();
+        paymentExecute.setPayerId(payerId);
+
+        APIContext apiContext = new APIContext("Bearer " + getAccessToken(paypalConfig));
+        Map<String, String> sdkConfig = new HashMap<>();
+        sdkConfig.put("mode", paypalConfig.getMode());
+        apiContext.setConfigurationMap(sdkConfig);
+
+        return payment.execute(apiContext, paymentExecute);
+    }
+
+    /**
+      * 获取token
+      * 了解更多:https://developer.paypal.com/webapps/developer/docs/integration/mobile/verify-mobile-payment/
+      * @return
+      */
+    private String getAccessToken(PaypalConfig paypalConfig) {
+        BufferedReader reader = null;
+        try {
+            URL url = new URL(UrlUtils.TOKEN_URL);
+            String authorization = paypalConfig.getClientId() + ":" + paypalConfig.getSecret();
+            authorization = Base64.encodeBase64String(authorization.getBytes());
+
+            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+            conn.setRequestMethod("POST");// 提交模式
+            //设置请求头header
+            conn.setRequestProperty("Accept", "application/json");
+            conn.setRequestProperty("Accept-Language", "en_US");
+            conn.setRequestProperty("Authorization", "Basic " + authorization);
+            // conn.setConnectTimeout(10000);//连接超时 单位毫秒
+            // conn.setReadTimeout(2000);//读取超时 单位毫秒
+            conn.setDoOutput(true);// 是否输入参数
+            String params = "grant_type=client_credentials";
+            conn.getOutputStream().write(params.getBytes());// 输入参数
+
+            InputStreamReader inStream = new InputStreamReader(conn.getInputStream());
+            reader = new BufferedReader(inStream);
+            StringBuilder result = new StringBuilder();
+            String lineTxt = null;
+            while ((lineTxt = reader.readLine()) != null) {
+                result.append(lineTxt);
+            }
+            reader.close();
+            String accessTokey = JSONObject.parseObject(result.toString()).getString("access_token");
+            log.info("getAccessToken:" + accessTokey);
+            return accessTokey;
+        } catch (Exception err) {
+            err.printStackTrace();
+        } finally {
+            if (reader != null){
+                try {
+                    reader.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        return null;
+    }
+
+    public String getPaymentDetails(String paymentId,PaypalConfig paypalConfig) {
+        BufferedReader reader = null;
+        try {
+            URL url = new URL(UrlUtils.PAYMENT_DETAIL + paymentId);
+            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+            conn.setRequestMethod("GET");// 提交模式
+            //设置请求头header
+            conn.setRequestProperty("Accept", "application/json");
+            conn.setRequestProperty("Authorization", "Bearer " + getAccessToken(paypalConfig));
+            // conn.setConnectTimeout(10000);//连接超时 单位毫秒
+            // conn.setReadTimeout(2000);//读取超时 单位毫秒
+            InputStreamReader inStream = new InputStreamReader(conn.getInputStream());
+            reader = new BufferedReader(inStream);
+            StringBuilder result = new StringBuilder();
+            String lineTxt = null;
+            while ((lineTxt = reader.readLine()) != null) {
+                result.append(lineTxt);
+            }
+            reader.close();
+            return result.toString();
+        } catch (Exception err) {
+            err.printStackTrace();
+        }finally {
+            if (reader != null){
+                try {
+                    reader.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        return null;
+    }
+
+    public boolean verifyPayment(String paymentId,PaypalConfig paypalConfig){
+        //从PayPal获取付款详情
+        String str = getPaymentDetails(paymentId,paypalConfig);
+        JSONObject detail = JSONObject.parseObject(str);
+        //校验订单是否完成
+        if("approved".equals(detail.getString("state"))){
+            JSONObject transactions = detail.getJSONArray("transactions").getJSONObject(0);
+            JSONObject amount = transactions.getJSONObject("amount");
+            JSONArray relatedResources = transactions.getJSONArray("related_resources");
+            //从数据库查询总金额与Paypal校验支付总金额
+            double total = 0;
+            if( total != amount.getDouble("total") ){
+                return false;
+            }
+            //校验交易货币类型
+            String currency = "USD";
+            if( !currency.equals(amount.getString("currency")) ){
+                return false;
+            }
+            //校验每个子订单是否完成
+            for (int i = 0,j = relatedResources.size(); i < j; i++) {
+                JSONObject sale = relatedResources.getJSONObject(i).getJSONObject("sale");
+                if( !"completed".equals(sale.getString("state")) ){
+                    System.out.println("子订单未完成,订单状态:"+sale.getString("state"));
+                }
+            }
+            return true;
+        }
+        return false;
+    }
+
+
+}

+ 5 - 0
src/main/resources/mapper/pay/PaypalConfigMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fdkankan.pay.mapper.IPaypalConfigMapper">
+
+</mapper>