Paypal支付接入(Android/IOS(swift)/Java后台)

本文章仅作为个人笔记

paypal开发者首页
paypal首页
paypalAndroidsdk项目地址
参考文章一(Android)
参考文章二(Android)
参考文章三(IOS)
paypal支付开发过程是漫长的,开始是各种paypal文档阅读,折腾了半天说clientid错误,弄了好久才发现github上面告知paypalsdk不再支持新商户,推荐使用 Braintree,然而再折腾半天,注册时发现Braintree只只是海外公司或香港公司,大陆公司根本无法注册,这就gg了。但肯定不能这么放弃啊,好在还是有大神的,经过几篇文章的合并,最后改出自己想要的方案。另外需要注意,如果想要开发收款则必须注册公司商务账号,并且保证对公账户paypal可用,注册时会看到相应的支持银行,这里由于前期开发过程过长,且注册过程什么的网上文章还是挺多的,就重造轮子了,这里主要贴自己的封装工具。
  • 部分信息获取方式截图

    • 进入Dashboard界面


      image.png
    • 进入app界面


      image.png
    • 查看clientId及secret,后面服务器及客户端均可用到,可根据个人需求决定sendbox用户或live用户。


      image.png
  • Android端

    • 导入方式官方demo已经说得非常清楚了,这里说个大概吧。

    • 添加jar包导入

          dependencies {
              api "com.paypal.sdk:paypal-android-sdk:2.16.0"
          }
      
    • 主要封装代码(因为楼主的商品都是一个一个购买的,所以封装的时候直接传入了一个商品,如果有多个商品同时购买并且包含税费、运费什么的可以自己修改此类):

          import android.app.Activity;
          import android.content.Intent;
          import android.util.Log;
          
          import com.paypal.android.sdk.payments.PayPalConfiguration;
          import com.paypal.android.sdk.payments.PayPalItem;
          import com.paypal.android.sdk.payments.PayPalPayment;
          import com.paypal.android.sdk.payments.PayPalPaymentDetails;
          import com.paypal.android.sdk.payments.PayPalService;
          import com.paypal.android.sdk.payments.PaymentActivity;
          import com.paypal.android.sdk.payments.PaymentConfirmation;
          
          import java.math.BigDecimal;
          
          public class PayPalUtils {
          //    private static final String CONFIG_ENVIRONMENT = PayPalConfiguration.ENVIRONMENT_SANDBOX;
              private static final String CONFIG_ENVIRONMENT = PayPalConfiguration.ENVIRONMENT_PRODUCTION;
              private static PayPalConfiguration config;
              private static final int REQUEST_CODE_PAY_PAL = 1008611;
              private static final PayPalUtils PAY_PAL_UTILS = new PayPalUtils();
              private static Activity activity;
              private static Back back;
          
              private PayPalUtils() {
              }
          
              public static PayPalUtils newInstance(Activity mActivity, String clientId, Back mBack) {
                  activity = mActivity;
                  back = mBack;
                  Intent intent = new Intent(activity, PayPalService.class);
                  config = new PayPalConfiguration()
                          .environment(CONFIG_ENVIRONMENT)
                          .clientId(clientId);
                  intent.putExtra(PayPalService.EXTRA_PAYPAL_CONFIGURATION, config);
                  activity.startService(intent);
                  return PAY_PAL_UTILS;
              }
          
              //价格,货币码(如:USD),商品名
              public void startPay(BigDecimal price, String currentcy, String goodsName, String orderNumber)          {
                  PayPalItem[] items = {new PayPalItem(goodsName, 1, price, currentcy, orderNumber)};
                  PayPalPaymentDetails paymentDetails = new PayPalPaymentDetails(
                          new BigDecimal(0), price, new BigDecimal(0));
                  PayPalPayment payment = new PayPalPayment(price, currentcy
                          , goodsName, PayPalPayment.PAYMENT_INTENT_SALE);
                  payment.items(items).paymentDetails(paymentDetails);
                  Intent intent = new Intent(activity, PaymentActivity.class);
                  intent.putExtra(PayPalService.EXTRA_PAYPAL_CONFIGURATION, config);
                  intent.putExtra(PaymentActivity.EXTRA_PAYMENT, payment);
                  activity.startActivityForResult(intent, REQUEST_CODE_PAY_PAL);
              }
          
              public void onActivityResult(int requestCode, int resultCode, Intent data) {
                  if (requestCode == REQUEST_CODE_PAY_PAL && back != null) {
                      if (resultCode == Activity.RESULT_OK) {
                          PaymentConfirmation paymentResult =
                                  data.getParcelableExtra(PaymentActivity.EXTRA_RESULT_CONFIRMATION);
                          back.onResult(paymentResult, paymentResult == null ? "payment result is null." :            null);
                      } else if (resultCode == Activity.RESULT_CANCELED) {
                          back.onResult(null, "user canceled.");
                      } else if (resultCode == PaymentActivity.RESULT_EXTRAS_INVALID) {
                          back.onResult(null, "An invalid Payment or PayPalConfiguration was submitted");
                      } else {
                          back.onResult(null, "unknow error.");
                      }
                  }
              }
          
              public void onDestroy() {
                  if (activity != null) {
                      activity.stopService(new Intent(activity, PayPalService.class));
                  }
                  activity = null;
                  back = null;
              }
          
              public interface Back {
                  public void onResult(PaymentConfirmation paymentResult, String errorMsg);
              }
          
          }
      
    • 封装代码使用方法:

      • 先实例化对象PayPalUtils.newInstance(),传入3个参数,第一个参数为activity本身,第二个参数为clientid(可从paypal后台获取),最后是支付回调方法,当errorMsg为空且paymentid不为空说明回调成功,否则支付失败。这里贴出示例:

              PayPalUtils payPalUtils = PayPalUtils.newInstance(this
                      , getString(R.string.paypal_client_id)//此处为paypalclientid
                      , new PayPalUtils.Back() {
                          @Override
                          public void onResult(PaymentConfirmation paymentResult, String errorMsg) {
                              if (errorMsg != null) {
                                  finishPay(errorMsg);
                              } else if (paymentResult != null && paymentResult.getProofOfPayment() != null
                                      && paymentResult.getProofOfPayment().getPaymentId() != null) {
                                      //订单号,上传至服务器校验
                                      String paymentId = paymentResult.getProofOfPayment().getPaymentId();
                              } else {
                                  finishPay(getString(R.string.a_l_pay_pay_field));
                              }
                          }
                      });
        
      • PayPalUtils对象建议放成员变量位,方便其他地方使用。获取好实例后记得在activity的onDestroy方法里调用payPalUtils.onDestroy();以及在onActivityResult方法调用payPalUtils.onActivityResult(requestCode, resultCode, data);

      • 最后最关键的调起支付方法(传入3个参数,第一个参数为价格,第二个参数为币码,如美元为USD,最后一个为商户订单号,即自己的订单号,当然这里的订单号也可以由服务器端生成或者用时间戳,自己抉择就好。):,客户端使用这个方法调起paypal支付后结果由之前的获取实例对象的回调完成支付结果回调。

              payPalUtils.startPay(new BigDecimal(currentItem.price), "USD", “OrderNumber”);
        
  • IOS端

    • 首先是导入第三方jar,在Podfile内加入如下代码,最后别忘了运行 pod install

      pod 'PayPal-iOS-SDK'
      
    • 导入完需要在头文件加入如下代码,同时如果发现报错,需要按照下面截图手动加入一些文件。

      #import <AlipaySDK/AlipaySDK.h>
      
image.png
  • 为了方便以后直接使用,直接创建了一个工具类,方便直接调用,下面贴出代码:

                class PayPalUtils {
                
                    static func initUtils(_ paypalLive: String, _  paypalSendBox: String, _ isSendBox: Bool) {
                        PayPalMobile.initializeWithClientIds(forEnvironments: [
                            PayPalEnvironmentProduction: paypalLive
                            , PayPalEnvironmentSandbox: paypalSendBox])
                        PayPalMobile.preconnect(withEnvironment: (isSendBox ? PayPalEnvironmentSandbox : PayPalEnvironmentProduction))
                    }
                
                    static func startPay(viewController: UIViewController, payPalPaymentDelegate: PayPalPaymentDelegate
                            , payAmount: Double, currencyCode: String, shortDescription: String) {
                        let payPalConfiguration = PayPalConfiguration()
                        payPalConfiguration.acceptCreditCards = true
                        payPalConfiguration.payPalShippingAddressOption = PayPalShippingAddressOption.payPal
                        payPalConfiguration.merchantName = NSLocalizedString("appName", comment: "")
                        payPalConfiguration.languageOrLocale = NSLocale.preferredLanguages.first
                        var payment = PayPalPayment()
                        payment.amount = NSDecimalNumber.init(string: String(format: "%.2f", arguments: [payAmount]))
                        payment.currencyCode = currencyCode
                        payment.shortDescription = shortDescription
                        payment.intent = PayPalPaymentIntent.sale
                        if !payment.processable {
                            print("订单信息错误")
                            return
                        }
                        let paymentViewController = PayPalPaymentViewController(payment: payment
                                , configuration: payPalConfiguration, delegate: payPalPaymentDelegate)
                        if paymentViewController != nil {
                            viewController.present(paymentViewController!
                                    , animated: true)
                        } else {
                            print("paymentViewController init error.")
                        }
                    }
                
                }
    
  • 完成这些步骤之后就是初始化paypal服务了,在AppDelegate.swift中初始化,下面贴核心代码部分(代码中用到了NSLocalizedString,也就是在Localizable.strings内赋值paypalLive和paypalSendBox,分别填入相应的ClientID,上面的截图有说明):

                func application(_ application: UIApplication, didFinishLaunchingWithOptions
                    launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
                    PayPalUtils.initUtils(NSLocalizedString("paypalLive", comment: ""), NSLocalizedString("paypalSendBox", comment: ""), false)
                    return true
                }
    
  • 初始化完成之后在需要调起支付的ViewController下实现paypal的支付回调:

            extension PlanCV: PayPalPaymentDelegate {
            
                func payPalPaymentDidCancel(_ paymentViewController: PayPalPaymentViewController) {
                    //运行到这里说明支付被取消
                    dismiss(animated: false)
                }
            
                func payPalPaymentViewController(_ paymentViewController: PayPalPaymentViewController
                        , didComplete completedPayment: PayPalPayment) {
                    do {
                        let paymentId = try ((completedPayment.confirmation as NSDictionary).object(forKey: "response") as! [String: String])["id"]
                        //可以将获取的paymentId直接上传至服务器处理,相关代码后面服务器部分已经说明
                    } catch {
                        //获取失败说明支付可能失败,做失败处理即可。
                    }
                    dismiss(animated: false)
                }
            
            }
    
  • 写好回调相应处理之后就可以直接在需要的地方直接调起支付了,需要传入5个参数,第一个参数为viewController本身,所以这里直接用了self,第二个为回调实现,因为也是基于ViewController实现的回调方法,这里也直接用了self,第三个参数为价格,写商品价格即可,Double类型,第4个参数为货币码,如美元是USD,第5个参数为商品名称,最后贴上调用代码:

            PayPalUtils.startPay(viewController: self, payPalPaymentDelegate: self, payAmount: price , currencyCode: "USD", shortDescription: name)
    
  • 服务器端

    • 先贴一个http请求封装工具

          import javax.net.ssl.HttpsURLConnection;
          import java.io.ByteArrayOutputStream;
          import java.io.InputStream;
          import java.net.HttpURLConnection;
          import java.net.Proxy;
          import java.net.URL;
          import java.util.HashMap;
          import java.util.List;
          import java.util.Map;
          
          /**
           * Created by marking on 2016/11/26.
           * 用于模拟http及https的got/post请求
           * <uses-permission android:name="android.permission.INTERNET" />
           */
          public class HttpUtils {
          
              private String HTTPS = "https";
              private String GET = "GET";
              private String POST = "POST";
              private static HttpUtils httpUtils;
          
              private HttpUtils() {
              }
          
              public static HttpUtils getInstance() {
                  if (httpUtils == null) {
                      httpUtils = new HttpUtils();
                  }
                  return httpUtils;
              }
          
              public interface IWebCallback {
          
                  void onCallback(int status, String message, Map<String, List<String>> heard, byte[] data);
          
                  void onFail(int status, String message);
          
              }
          
              public byte[] getURLResponse(String urlString, HashMap<String, String> heads) {
                  byte[] result = null;
                  if (urlString != null) {
                      HttpURLConnection conn = null; //连接对象
                      InputStream is = null;
                      ByteArrayOutputStream baos = null;
                      try {
                          URL url = new URL(urlString); //URL对象
                          if (urlString.startsWith(HTTPS)) {
                              conn = (HttpsURLConnection) url.openConnection();
                          } else {
                              conn = (HttpURLConnection) url.openConnection();
                          }
                          conn.setConnectTimeout(5 * 1000);
                          conn.setDoOutput(true);
                          conn.setRequestMethod(GET);
                          if (heads != null) {
                              for (String key : heads.keySet()) {
                                  conn.addRequestProperty(key, heads.get(key));
                              }
                          }
                          is = conn.getInputStream();   //获取输入流,此时才真正建立链接
                          baos = new ByteArrayOutputStream();
                          byte[] temp = new byte[1024];
                          int len;
                          while ((len = is.read(temp)) != -1) {
                              baos.write(temp, 0, len);
                          }
                          result = baos.toByteArray();
                      } catch (Exception e) {
                      } finally {
                          CloseUtils.closeSilently(is);
                          CloseUtils.closeSilently(baos);
                          if (conn != null) {
                              conn.disconnect();
                          }
                      }
                  }
                  return result;
              }
          
              public void getURLResponse(String urlString, HashMap<String, String> heads, IWebCallback iWebCallback) {
                  getURLResponse(urlString, heads, null, iWebCallback);
              }
          
              public void getURLResponse(String urlString, HashMap<String, String> heads, Proxy proxy, IWebCallback iWebCallback) {
                  if (urlString != null) {
                      HttpURLConnection conn = null; //连接对象
                      InputStream is = null;
                      ByteArrayOutputStream baos = null;
                      try {
                          URL url = new URL(urlString); //URL对象
                          if (proxy == null) {
                              if (urlString.startsWith(HTTPS)) {
                                  conn = (HttpsURLConnection) url.openConnection();
                              } else {
                                  conn = (HttpURLConnection) url.openConnection();
                              }
                          } else {
                              if (urlString.startsWith(HTTPS)) {
                                  conn = (HttpsURLConnection) url.openConnection(proxy);
                              } else {
                                  conn = (HttpURLConnection) url.openConnection(proxy);
                              }
                          }
                          conn.setConnectTimeout(5 * 1000);
                          conn.setDoOutput(true);
                          conn.setRequestMethod(GET);
                          if (heads != null) {
                              for (String key : heads.keySet()) {
                                  conn.addRequestProperty(key, heads.get(key));
                              }
                          }
                          is = conn.getInputStream();   //获取输入流,此时才真正建立链接
                          baos = new ByteArrayOutputStream();
                          byte[] temp = new byte[1024];
                          int len;
                          while ((len = is.read(temp)) != -1) {
                              baos.write(temp, 0, len);
                          }
                          if (iWebCallback != null) {
                              iWebCallback.onCallback(conn.getResponseCode(), conn.getResponseMessage(), conn.getHeaderFields(), baos.toByteArray());
                          }
                      } catch (Exception e) {
                          int code = 600;
                          try {
                              code = conn == null ? 600 : conn.getResponseCode();
                          } catch (Exception e1) {
                          }
                          if (iWebCallback != null) {
                              iWebCallback.onFail(code, e.toString());
                          }
                      } finally {
                          CloseUtils.closeSilently(is);
                          CloseUtils.closeSilently(baos);
                          if (conn != null) {
                              conn.disconnect();
                          }
                      }
                  }
              }
          
              public byte[] postURLResponse(String urlString, HashMap<String, String> headers, byte[] postData) {
                  byte[] result = null;
                  if (urlString != null) {
                      HttpURLConnection conn = null; //连接对象
                      InputStream is = null;
                      ByteArrayOutputStream baos = null;
                      try {
                          URL url = new URL(urlString); //URL对象
                          if (urlString.startsWith(HTTPS)) {
                              conn = (HttpsURLConnection) url.openConnection();
                          } else {
                              conn = (HttpURLConnection) url.openConnection();
                          }
                          conn.setConnectTimeout(5 * 1000);
                          conn.setDoOutput(true);
                          conn.setRequestMethod(POST); //使用post请求
                          conn.setRequestProperty("Charsert", "UTF-8");
                          if (headers != null) {
                              for (Map.Entry<String, String> temp : headers.entrySet()) {
                                  conn.setRequestProperty(temp.getKey(), temp.getValue());
                              }
                          }
                          conn.getOutputStream().write(postData);
                          is = conn.getInputStream();   //获取输入流,此时才真正建立链接
                          baos = new ByteArrayOutputStream();
                          byte[] temp = new byte[1024];
                          int len;
                          while ((len = is.read(temp)) != -1) {
                              baos.write(temp, 0, len);
                          }
                          result = baos.toByteArray();
                      } catch (Exception e) {
                      } finally {
                          CloseUtils.closeSilently(is);
                          CloseUtils.closeSilently(baos);
                          if (conn != null) {
                              conn.disconnect();
                          }
                      }
                  }
                  return result;
              }
          
              public void postURLResponse(String urlString, HashMap<String, String> headers,
                                          byte[] postData, IWebCallback iWebCallback) {
                  if (urlString != null) {
                      HttpURLConnection conn = null; //连接对象
                      InputStream is = null;
                      ByteArrayOutputStream baos = null;
                      try {
                          URL url = new URL(urlString); //URL对象
                          if (urlString.startsWith(HTTPS)) {
                              conn = (HttpsURLConnection) url.openConnection();
                          } else {
                              conn = (HttpURLConnection) url.openConnection();
                          }
                          conn.setConnectTimeout(5 * 1000);
                          conn.setDoOutput(true);
                          conn.setRequestMethod(POST); //使用post请求
                          conn.setRequestProperty("Charsert", "UTF-8");
                          if (headers != null) {
                              for (Map.Entry<String, String> temp : headers.entrySet()) {
                                  conn.setRequestProperty(temp.getKey(), temp.getValue());
                              }
                          }
                          conn.getOutputStream().write(postData);
                          is = conn.getInputStream();   //获取输入流,此时才真正建立链接
                          baos = new ByteArrayOutputStream();
                          byte[] temp = new byte[1024];
                          int len;
                          while ((len = is.read(temp)) != -1) {
                              baos.write(temp, 0, len);
                          }
                          if (iWebCallback != null) {
                              iWebCallback.onCallback(conn.getResponseCode(), conn.getResponseMessage(), conn.getHeaderFields(), baos.toByteArray());
                          }
                      } catch (Exception e) {
                          int code = 600;
                          try {
                              code = conn == null ? 600 : conn.getResponseCode();
                          } catch (Exception e1) {
                          }
                          if (iWebCallback != null) {
                              iWebCallback.onFail(code, e.toString());
                          }
                      } finally {
                          CloseUtils.closeSilently(is);
                          CloseUtils.closeSilently(baos);
                          if (conn != null) {
                              conn.disconnect();
                          }
                      }
                  }
              }
          }
      
    • 主要工具类,为了方便使用,全放一个类里边了,另外由于返回的数据结构实在复杂,所以后面的对象代码偏多,主要看前面几个方法便好。

          import com.alibaba.fastjson.JSON;
          import org.apache.tomcat.util.codec.binary.Base64;
          
          import java.util.ArrayList;
          import java.util.HashMap;
          
          public class PayPalUtils {
          
          
          //    private static final String TOKEN_URL = "https://api.sandbox.paypal.com/v1/oauth2/token";//沙箱链接
          //    private static final String PAYMENT_DETAIL = "https://api.sandbox.paypal.com/v1/payments/payment/";//沙箱链接
              private static final String TOKEN_URL = "https://api.paypal.com/v1/oauth2/token";
              private static final String PAYMENT_DETAIL = "https://api.paypal.com/v1/payments/payment/";
              private static final String clientId = "";//这两个参数应该很容易在paypal开发者页面找到,文中会贴出截图
              private static final String secret = "";
          
              private static String getAccessToken() {
                  byte[] resultBytes = HttpUtils.getInstance().postURLResponse(TOKEN_URL, new HashMap<String, String>() {{
                      put("Accept", "application/json");
                      put("Accept-Language", "en_US");
                      put("Authorization", "Basic " + Base64.encodeBase64String((clientId + ":" + secret).getBytes()));
                  }}, "grant_type=client_credentials".getBytes());
                  ResponseToken result = resultBytes == null ? null : JSON.parseObject(new String(resultBytes), ResponseToken.class);
                  return result == null ? null : result.accessToken;
              }
          
              private static ResponsePayPayl getResponsePayPayl(String paymentId) {
                  String token = getAccessToken();
                  if (token == null) {
                      System.out.println("verify paypal payment get token error.");
                      return null;
                  }
                  byte[] resultBytes = HttpUtils.getInstance().getURLResponse(PAYMENT_DETAIL + paymentId
                          , new HashMap<String, String>() {{
                              put("Accept", "application/json");
                              put("Authorization", "Bearer " + token);
                          }});
                  return resultBytes == null ? null : JSON.parseObject(new String(resultBytes), ResponsePayPayl.class);
              }
          
              public static boolean isSuccess(String paymentId) {
                  ResponsePayPayl responsePayPayl = getResponsePayPayl(paymentId);
                  System.out.println("paypal.state=" + (responsePayPayl == null ? "null" : responsePayPayl.state));
                  return responsePayPayl != null && "approved".equals(responsePayPayl.state);
              }
          
              public static String getOrderNumber(String paymentId) {
                  ResponsePayPayl responsePayPayl = getResponsePayPayl(paymentId);
                  if (responsePayPayl != null && responsePayPayl.transactions != null
                          && responsePayPayl.transactions.size() > 0 && responsePayPayl.transactions.get(0).itemList != null
                          && responsePayPayl.transactions.get(0).itemList.items != null
                          && responsePayPayl.transactions.get(0).itemList.items.size() > 0) {
                      return responsePayPayl.transactions.get(0).itemList.items.get(0).sku;
                  }
                  return null;
              }
          
              public static class ResponsePayPayl {
                  private String id;
                  private String intent;
                  private String state;
                  private String cart;
                  private Payer payer;
                  private ArrayList<Transaction> transactions;
                  private String createTime;
                  private ArrayList<Link> links;
          
                  public String getId() {
                      return id;
                  }
          
                  public void setId(String id) {
                      this.id = id;
                  }
          
                  public String getIntent() {
                      return intent;
                  }
          
                  public void setIntent(String intent) {
                      this.intent = intent;
                  }
          
                  public String getState() {
                      return state;
                  }
          
                  public void setState(String state) {
                      this.state = state;
                  }
          
                  public String getCart() {
                      return cart;
                  }
          
                  public void setCart(String cart) {
                      this.cart = cart;
                  }
          
                  public Payer getPayer() {
                      return payer;
                  }
          
                  public void setPayer(Payer payer) {
                      this.payer = payer;
                  }
          
                  public ArrayList<Transaction> getTransactions() {
                      return transactions;
                  }
          
                  public void setTransactions(ArrayList<Transaction> transactions) {
                      this.transactions = transactions;
                  }
          
                  public String getCreateTime() {
                      return createTime;
                  }
          
                  public void setCreateTime(String createTime) {
                      this.createTime = createTime;
                  }
          
                  public ArrayList<Link> getLinks() {
                      return links;
                  }
          
                  public void setLinks(ArrayList<Link> links) {
                      this.links = links;
                  }
          
                  @Override
                  public String toString() {
                      return "ResponsePayPayl{" +
                              "id='" + id + '\'' +
                              ", intent='" + intent + '\'' +
                              ", state='" + state + '\'' +
                              ", cart='" + cart + '\'' +
                              ", payer=" + payer +
                              ", transactions=" + transactions +
                              ", createTime='" + createTime + '\'' +
                              ", links=" + links +
                              '}';
                  }
              }
          
              public static class Transaction {
          
                  private Amount amount;
                  private Payee payee;
                  private String description;
                  private ItemList itemList;
                  private ArrayList<RelatedResource> relatedResources;
          
                  public Amount getAmount() {
                      return amount;
                  }
          
                  public void setAmount(Amount amount) {
                      this.amount = amount;
                  }
          
                  public Payee getPayee() {
                      return payee;
                  }
          
                  public void setPayee(Payee payee) {
                      this.payee = payee;
                  }
          
                  public String getDescription() {
                      return description;
                  }
          
                  public void setDescription(String description) {
                      this.description = description;
                  }
          
                  public ItemList getItemList() {
                      return itemList;
                  }
          
                  public void setItemList(ItemList itemList) {
                      this.itemList = itemList;
                  }
          
                  public ArrayList<RelatedResource> getRelatedResources() {
                      return relatedResources;
                  }
          
                  public void setRelatedResources(ArrayList<RelatedResource> relatedResources) {
                      this.relatedResources = relatedResources;
                  }
          
                  @Override
                  public String toString() {
                      return "Transaction{" +
                              "amount=" + amount +
                              ", payee=" + payee +
                              ", description='" + description + '\'' +
                              ", itemList=" + itemList +
                              ", relatedResources=" + relatedResources +
                              '}';
                  }
              }
          
              public static class RelatedResource {
                  private Sale sale;
          
                  public Sale getSale() {
                      return sale;
                  }
          
                  public void setSale(Sale sale) {
                      this.sale = sale;
                  }
          
                  @Override
                  public String toString() {
                      return "RelatedResource{" +
                              "sale=" + sale +
                              '}';
                  }
              }
          
              public static class Sale {
          
                  private String id;
                  private String state;
                  private Amount amount;
                  private String paymentMode;
                  private String protectionEligibility;
                  private String protectionEligibilityType;
                  private TransactionFee transactionFee;
                  private String parentPayment;
                  private String createTime;
                  private String updateTime;
                  private ArrayList<Link> links;
          
                  public String getId() {
                      return id;
                  }
          
                  public void setId(String id) {
                      this.id = id;
                  }
          
                  public String getState() {
                      return state;
                  }
          
                  public void setState(String state) {
                      this.state = state;
                  }
          
                  public Amount getAmount() {
                      return amount;
                  }
          
                  public void setAmount(Amount amount) {
                      this.amount = amount;
                  }
          
                  public String getPaymentMode() {
                      return paymentMode;
                  }
          
                  public void setPaymentMode(String paymentMode) {
                      this.paymentMode = paymentMode;
                  }
          
                  public String getProtectionEligibility() {
                      return protectionEligibility;
                  }
          
                  public void setProtectionEligibility(String protectionEligibility) {
                      this.protectionEligibility = protectionEligibility;
                  }
          
                  public String getProtectionEligibilityType() {
                      return protectionEligibilityType;
                  }
          
                  public void setProtectionEligibilityType(String protectionEligibilityType) {
                      this.protectionEligibilityType = protectionEligibilityType;
                  }
          
                  public TransactionFee getTransactionFee() {
                      return transactionFee;
                  }
          
                  public void setTransactionFee(TransactionFee transactionFee) {
                      this.transactionFee = transactionFee;
                  }
          
                  public String getParentPayment() {
                      return parentPayment;
                  }
          
                  public void setParentPayment(String parentPayment) {
                      this.parentPayment = parentPayment;
                  }
          
                  public String getCreateTime() {
                      return createTime;
                  }
          
                  public void setCreateTime(String createTime) {
                      this.createTime = createTime;
                  }
          
                  public String getUpdateTime() {
                      return updateTime;
                  }
          
                  public void setUpdateTime(String updateTime) {
                      this.updateTime = updateTime;
                  }
          
                  public ArrayList<Link> getLinks() {
                      return links;
                  }
          
                  public void setLinks(ArrayList<Link> links) {
                      this.links = links;
                  }
          
                  @Override
                  public String toString() {
                      return "Sale{" +
                              "id='" + id + '\'' +
                              ", state='" + state + '\'' +
                              ", amount=" + amount +
                              ", paymentMode='" + paymentMode + '\'' +
                              ", protectionEligibility='" + protectionEligibility + '\'' +
                              ", protectionEligibilityType='" + protectionEligibilityType + '\'' +
                              ", transactionFee=" + transactionFee +
                              ", parentPayment='" + parentPayment + '\'' +
                              ", createTime='" + createTime + '\'' +
                              ", updateTime='" + updateTime + '\'' +
                              ", links=" + links +
                              '}';
                  }
              }
          
              public static class TransactionFee {
                  private String value;
                  private String currency;
          
                  public String getValue() {
                      return value;
                  }
          
                  public void setValue(String value) {
                      this.value = value;
                  }
          
                  public String getCurrency() {
                      return currency;
                  }
          
                  public void setCurrency(String currency) {
                      this.currency = currency;
                  }
          
                  @Override
                  public String toString() {
                      return "TransactionFee{" +
                              "value='" + value + '\'' +
                              ", currency='" + currency + '\'' +
                              '}';
                  }
              }
          
              public static class ItemList {
          
                  private ArrayList<Item> items;
                  private ShippingAddress shippingAddress;
          
                  public ArrayList<Item> getItems() {
                      return items;
                  }
          
                  public void setItems(ArrayList<Item> items) {
                      this.items = items;
                  }
          
                  public ShippingAddress getShippingAddress() {
                      return shippingAddress;
                  }
          
                  public void setShippingAddress(ShippingAddress shippingAddress) {
                      this.shippingAddress = shippingAddress;
                  }
          
                  @Override
                  public String toString() {
                      return "ItemList{" +
                              "items=" + items +
                              ", shippingAddress=" + shippingAddress +
                              '}';
                  }
              }
          
              public static class Item {
                  private String name;
                  private String sku;
                  private String price;
                  private String currency;
                  private String tax;
                  private int quantity;
          
                  public String getName() {
                      return name;
                  }
          
                  public void setName(String name) {
                      this.name = name;
                  }
          
                  public String getSku() {
                      return sku;
                  }
          
                  public void setSku(String sku) {
                      this.sku = sku;
                  }
          
                  public String getPrice() {
                      return price;
                  }
          
                  public void setPrice(String price) {
                      this.price = price;
                  }
          
                  public String getCurrency() {
                      return currency;
                  }
          
                  public void setCurrency(String currency) {
                      this.currency = currency;
                  }
          
                  public String getTax() {
                      return tax;
                  }
          
                  public void setTax(String tax) {
                      this.tax = tax;
                  }
          
                  public int getQuantity() {
                      return quantity;
                  }
          
                  public void setQuantity(int quantity) {
                      this.quantity = quantity;
                  }
          
                  @Override
                  public String toString() {
                      return "Item{" +
                              "name='" + name + '\'' +
                              ", sku='" + sku + '\'' +
                              ", price='" + price + '\'' +
                              ", currency='" + currency + '\'' +
                              ", tax='" + tax + '\'' +
                              ", quantity=" + quantity +
                              '}';
                  }
              }
          
              public static class Payee {
                  private String merchantId;
          
                  public String getMerchantId() {
                      return merchantId;
                  }
          
                  public void setMerchantId(String merchantId) {
                      this.merchantId = merchantId;
                  }
          
                  @Override
                  public String toString() {
                      return "Payee{" +
                              "merchantId='" + merchantId + '\'' +
                              '}';
                  }
              }
          
              public static class Amount {
                  private String total;
                  private String currency;
                  private Details details;
          
                  public String getTotal() {
                      return total;
                  }
          
                  public void setTotal(String total) {
                      this.total = total;
                  }
          
                  public String getCurrency() {
                      return currency;
                  }
          
                  public void setCurrency(String currency) {
                      this.currency = currency;
                  }
          
                  public Details getDetails() {
                      return details;
                  }
          
                  public void setDetails(Details details) {
                      this.details = details;
                  }
          
                  @Override
                  public String toString() {
                      return "Amount{" +
                              "total='" + total + '\'' +
                              ", currency='" + currency + '\'' +
                              ", details=" + details +
                              '}';
                  }
              }
          
              public static class Details {
                  private String subtotal;
          
                  public String getSubtotal() {
                      return subtotal;
                  }
          
                  public void setSubtotal(String subtotal) {
                      this.subtotal = subtotal;
                  }
          
                  @Override
                  public String toString() {
                      return "Details{" +
                              "subtotal='" + subtotal + '\'' +
                              '}';
                  }
              }
          
              public static class Link {
                  private String links;
                  private String rel;
                  private String method;
          
                  public String getLinks() {
                      return links;
                  }
          
                  public void setLinks(String links) {
                      this.links = links;
                  }
          
                  public String getRel() {
                      return rel;
                  }
          
                  public void setRel(String rel) {
                      this.rel = rel;
                  }
          
                  public String getMethod() {
                      return method;
                  }
          
                  public void setMethod(String method) {
                      this.method = method;
                  }
          
                  @Override
                  public String toString() {
                      return "Link{" +
                              "links='" + links + '\'' +
                              ", rel='" + rel + '\'' +
                              ", method='" + method + '\'' +
                              '}';
                  }
              }
          
              public static class Payer {
                  private String paymentMethod;
                  private String status;
                  private PayerInfo payerInfo;
          
                  public String getPaymentMethod() {
                      return paymentMethod;
                  }
          
                  public void setPaymentMethod(String paymentMethod) {
                      this.paymentMethod = paymentMethod;
                  }
          
                  public String getStatus() {
                      return status;
                  }
          
                  public void setStatus(String status) {
                      this.status = status;
                  }
          
                  public PayerInfo getPayerInfo() {
                      return payerInfo;
                  }
          
                  public void setPayerInfo(PayerInfo payerInfo) {
                      this.payerInfo = payerInfo;
                  }
          
                  @Override
                  public String toString() {
                      return "Payer{" +
                              "paymentMethod='" + paymentMethod + '\'' +
                              ", status='" + status + '\'' +
                              ", payerInfo=" + payerInfo +
                              '}';
                  }
              }
          
              public static class PayerInfo {
                  private String email;
                  private String firstName;
                  private String lastName;
                  private String payerId;
                  private ShippingAddress shippingAddress;
                  private String phone;
                  private String countryCode;
          
                  public String getEmail() {
                      return email;
                  }
          
                  public void setEmail(String email) {
                      this.email = email;
                  }
          
                  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 getPayerId() {
                      return payerId;
                  }
          
                  public void setPayerId(String payerId) {
                      this.payerId = payerId;
                  }
          
                  public ShippingAddress getShippingAddress() {
                      return shippingAddress;
                  }
          
                  public void setShippingAddress(ShippingAddress shippingAddress) {
                      this.shippingAddress = shippingAddress;
                  }
          
                  public String getPhone() {
                      return phone;
                  }
          
                  public void setPhone(String phone) {
                      this.phone = phone;
                  }
          
                  public String getCountryCode() {
                      return countryCode;
                  }
          
                  public void setCountryCode(String countryCode) {
                      this.countryCode = countryCode;
                  }
          
                  @Override
                  public String toString() {
                      return "PayerInfo{" +
                              "email='" + email + '\'' +
                              ", firstName='" + firstName + '\'' +
                              ", lastName='" + lastName + '\'' +
                              ", payerId='" + payerId + '\'' +
                              ", shippingAddress=" + shippingAddress +
                              ", phone='" + phone + '\'' +
                              ", countryCode='" + countryCode + '\'' +
                              '}';
                  }
              }
          
              public static class ShippingAddress {
                  private String recipientName;
          
                  public String getRecipientName() {
                      return recipientName;
                  }
          
                  public void setRecipientName(String recipientName) {
                      this.recipientName = recipientName;
                  }
          
                  @Override
                  public String toString() {
                      return "ShippingAddress{" +
                              "recipientName='" + recipientName + '\'' +
                              '}';
                  }
              }
          
              public static class ResponseToken {
                  private String scope;
                  private String nonce;
                  private String accessToken;
                  private String tokenType;
                  private String appId;
                  private int expiresIn;
          
                  public String getScope() {
                      return scope;
                  }
          
                  public void setScope(String scope) {
                      this.scope = scope;
                  }
          
                  public String getNonce() {
                      return nonce;
                  }
          
                  public void setNonce(String nonce) {
                      this.nonce = nonce;
                  }
          
                  public String getAccessToken() {
                      return accessToken;
                  }
          
                  public void setAccessToken(String accessToken) {
                      this.accessToken = accessToken;
                  }
          
                  public String getTokenType() {
                      return tokenType;
                  }
          
                  public void setTokenType(String tokenType) {
                      this.tokenType = tokenType;
                  }
          
                  public String getAppId() {
                      return appId;
                  }
          
                  public void setAppId(String appId) {
                      this.appId = appId;
                  }
          
                  public int getExpiresIn() {
                      return expiresIn;
                  }
          
                  public void setExpiresIn(int expiresIn) {
                      this.expiresIn = expiresIn;
                  }
          
                  @Override
                  public String toString() {
                      return "ResponseToken{" +
                              "scope='" + scope + '\'' +
                              ", nonce='" + nonce + '\'' +
                              ", accessToken='" + accessToken + '\'' +
                              ", tokenType='" + tokenType + '\'' +
                              ", appId='" + appId + '\'' +
                              ", expiresIn=" + expiresIn +
                              '}';
                  }
              }
          
          }
      
    • 最后是工具类PayPalUtils的使用方法,主要分2种,一种是直接判断是否支付成功的isSuccess(),一种是获取客户端生成的订单号(可能包含产品信息等)getOrderNumber(),两者都是传入一个参数,即客户端上传的paymentId,当然也可以根据自己的喜好改动,里边的getResponsePayPayl()方法可以获取返回的所有信息。楼主使用的是getOrderNumber(),另外为了给paypal足够的处理时间,建议如果一次获取不到订单号或者判断支付失败的可进行多次间隔校验。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容

  • 有你的日子,每天都是节日;有你的日子,每件事都会顺利。 你就是上帝对我的眷顾,让我陶醉。就是我的全部,失去你就是失...
    黑马非凡马阅读 201评论 0 6
  • 路漫漫人生繁华, 孤寂凄凉又人绝。 奈何情长而缘浅, 人生在世一声叹。
    二智啊阅读 273评论 0 3
  • 爸爸和妈妈在亲吻。 回头看见一个小朋友抬着头,眯眯笑着在看。 爸爸妈妈把小朋友拉过来,从左边和右边给了他一个亲吻。
    明亮中正阅读 119评论 0 0
  • 响应组长号召,精简笔记字数。 第五章的标题是“调试”,所以作者先举了一些大脑可能会犯的认知错误例子,告诉我们哪里最...
    要饭熊阅读 137评论 0 0
  • 这几天我在干什么呢!我在看狗,我在给狗准备饭,给狗铲屎擦尿,开始它总在床上尿尿,甚至是拉屎。我每次都对它施以暴力,...
    嘎旺阅读 164评论 0 0