• 最详细的 paypal 支付接口开发--Java版


    做全球性的支付,选用paypal!为什么选择paypal? 因为paypal是目前全球最大的在线支付工具,就像国内的支付宝一样,是一个基于买卖双方的第三方平台。买家只需知道你的paypal账号,即可在线直接把钱汇入你的账户,即时到账,简单方便快捷。


    在集成paypal支付接口之前,首先要有一系列的准备,开发者账号啊、sdk、测试环境等等先要有,然后再码代码。集成的步骤如下:


    一、环境准备

    • 注册paypal账号

    • 注册paypal开发者账号

    • 创建两个测试用户

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

    二、代码集成

    • springboot环境

    • pom引进paypal-sdk的jar包

    • 码代码

    • 测试

    • 后言


      现在开始


    • 注册paypal账号

    (1)在浏览器输入“https://www.paypal.com” 跳转到如下界面,点击右上角的注册

    这里写图片描述

    (2)选择,”创建商家用户”,根据要求填写信息,一分钟的事,注册完得去邮箱激活



    这里写图片描述


    • 注册paypal开发者账号


      (1)在浏览器输入“https://developer.paypal.com”,点击右上角的“Log into Dashboard”,用上一步创建好的账号登录



    这里写图片描述


    • 创建两个测试用户

    (1)登录成功后,在左边的导航栏中点击 Sandbox 下的 Accounts



    这里写图片描述

    (2)进入Acccouts界面后,可以看到系统有两个已经生成好的测试账号,但是我们不要用系统给的测试账号,很卡的,自己创建两个

    这里写图片描述

    (3)点击右上角的“Create Account”,创建测试用户

    这里写图片描述



    <1> 先创建一个“ PERSONAL”类型的用户,国家一定要选“China”,账户余额自己填写

    这里写图片描述


    这里写图片描述

    <2> 接着创建一个“BUSINESS”类型的用户,国家一定要选“China”,账户余额自己填写

    这里写图片描述



    <3>创建好之后可以点击测试账号下的”Profile“,可以查看信息,如果没加载出来,刷新

    这里写图片描述

    <4>用测试账号登录测试网站查看,注意!这跟paypal官网不同!不是同一个地址,在浏览器输入:https://www.sandbox.paypal.com 在这里登陆测试账户


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


      (1)点击左边导航栏Dashboard下的My Apps & Credentials,创建一个Live账号,下图是我已经创建好的

    这里写图片描述



    (2)然后再到下边创建App



    这里写图片描述



    这是我创建好的“Test”App

    这里写图片描述

    (3)点击刚刚创建好的App“Test”,注意看到”ClientID“ 和”Secret“(Secret如果没显示,点击下面的show就会看到,点击后show变为hide)

    这里写图片描述


    • springboot环境搭建


      (1)新建几个包,和目录,项目结构如下

    这里写图片描述


    • pom引进paypal-sdk的jar包


      (1)pom.xml
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>com.masasdani</groupId>
      <artifactId>paypal-springboot</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <name>paypal-springboot</name>
    
      <repositories>
            <repository>
                <id>spring-milestones</id>
                <name>Spring Milestones</name>
                <url>http://repo.spring.io/libs-milestone</url>
            </repository>
            <repository>
                <id>jcenter-snapshots</id>
                <name>jcenter</name>
                <url>https://jcenter.bintray.com/</url>
            </repository>
        </repositories>
    
        <pluginRepositories>
            <pluginRepository>
                <id>spring-milestones</id>
                <name>Spring Milestones</name>
                <url>http://repo.spring.io/libs-milestone</url>
            </pluginRepository>
        </pluginRepositories>
    
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>1.3.0.RELEASE</version>
        </parent>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <java.version>1.7</java.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-thymeleaf</artifactId>
            </dependency>
            <dependency>
                <groupId>com.paypal.sdk</groupId>
                <artifactId>rest-api-sdk</artifactId>
                <version>1.4.2</version>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <configuration>
                        <source>${java.version}</source>
                        <target>${java.version}</target>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </project>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68


    • 码代码


      (1)Application.java
    package com.masasdani.paypal;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    
    @EnableAutoConfiguration
    @Configuration
    @ComponentScan
    public class Application {
    
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
        }
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16



    (2)PaypalConfig.java

    package com.masasdani.paypal.config;
    
    import java.util.HashMap;
    import java.util.Map;
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    import com.paypal.base.rest.APIContext;
    import com.paypal.base.rest.OAuthTokenCredential;
    import com.paypal.base.rest.PayPalRESTException;
    
    @Configuration
    public class PaypalConfig {
    
        @Value("${paypal.client.app}")
        private String clientId;
        @Value("${paypal.client.secret}")
        private String clientSecret;
        @Value("${paypal.mode}")
        private String mode;
    
        @Bean
        public Map<String, String> paypalSdkConfig(){
            Map<String, String> sdkConfig = new HashMap<>();
            sdkConfig.put("mode", mode);
            return sdkConfig;
        }
    
        @Bean
        public OAuthTokenCredential authTokenCredential(){
            return new OAuthTokenCredential(clientId, clientSecret, paypalSdkConfig());
        }
    
        @Bean
        public APIContext apiContext() throws PayPalRESTException{
            APIContext apiContext = new APIContext(authTokenCredential().getAccessToken());
            apiContext.setConfigurationMap(paypalSdkConfig());
            return apiContext;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43



    (3)PaypalPaymentIntent.java

    package com.masasdani.paypal.config;
    
    public enum PaypalPaymentIntent {
    
        sale, authorize, order
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8



    (4)PaypalPaymentMethod.java

    package com.masasdani.paypal.config;
    
    public enum PaypalPaymentMethod {
    
        credit_card, paypal
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8



    (5)PaymentController.java

    package com.masasdani.paypal.controller;
    
    import javax.servlet.http.HttpServletRequest;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RequestParam;
    
    import com.masasdani.paypal.config.PaypalPaymentIntent;
    import com.masasdani.paypal.config.PaypalPaymentMethod;
    import com.masasdani.paypal.service.PaypalService;
    import com.masasdani.paypal.util.URLUtils;
    import com.paypal.api.payments.Links;
    import com.paypal.api.payments.Payment;
    import com.paypal.base.rest.PayPalRESTException;
    
    @Controller
    @RequestMapping("/")
    public class PaymentController {
    
        public static final String PAYPAL_SUCCESS_URL = "pay/success";
        public static final String PAYPAL_CANCEL_URL = "pay/cancel";
    
        private Logger log = LoggerFactory.getLogger(getClass());
    
        @Autowired
        private PaypalService paypalService;
    
        @RequestMapping(method = RequestMethod.GET)
        public String index(){
            return "index";
        }
    
        @RequestMapping(method = RequestMethod.POST, value = "pay")
        public String pay(HttpServletRequest request){
            String cancelUrl = URLUtils.getBaseURl(request) + "/" + PAYPAL_CANCEL_URL;
            String successUrl = URLUtils.getBaseURl(request) + "/" + PAYPAL_SUCCESS_URL;
            try {
                Payment payment = paypalService.createPayment(
                        500.00, 
                        "USD", 
                        PaypalPaymentMethod.paypal, 
                        PaypalPaymentIntent.sale,
                        "payment description", 
                        cancelUrl, 
                        successUrl);
                for(Links links : payment.getLinks()){
                    if(links.getRel().equals("approval_url")){
                        return "redirect:" + links.getHref();
                    }
                }
            } catch (PayPalRESTException e) {
                log.error(e.getMessage());
            }
            return "redirect:/";
        }
    
        @RequestMapping(method = RequestMethod.GET, value = PAYPAL_CANCEL_URL)
        public String cancelPay(){
            return "cancel";
        }
    
        @RequestMapping(method = RequestMethod.GET, value = PAYPAL_SUCCESS_URL)
        public String successPay(@RequestParam("paymentId") String paymentId, @RequestParam("PayerID") String payerId){
            try {
                Payment payment = paypalService.executePayment(paymentId, payerId);
                if(payment.getState().equals("approved")){
                    return "success";
                }
            } catch (PayPalRESTException e) {
                log.error(e.getMessage());
            }
            return "redirect:/";
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81



    (6)PaypalService.java

    package com.masasdani.paypal.service;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import com.masasdani.paypal.config.PaypalPaymentIntent;
    import com.masasdani.paypal.config.PaypalPaymentMethod;
    import com.paypal.api.payments.Amount;
    import com.paypal.api.payments.Payer;
    import com.paypal.api.payments.Payment;
    import com.paypal.api.payments.PaymentExecution;
    import com.paypal.api.payments.RedirectUrls;
    import com.paypal.api.payments.Transaction;
    import com.paypal.base.rest.APIContext;
    import com.paypal.base.rest.PayPalRESTException;
    
    @Service
    public class PaypalService {
    
        @Autowired
        private APIContext apiContext;
    
        public Payment createPayment(
                Double total, 
                String currency, 
                PaypalPaymentMethod method, 
                PaypalPaymentIntent intent, 
                String description, 
                String cancelUrl, 
                String successUrl) throws PayPalRESTException{
            Amount amount = new Amount();
            amount.setCurrency(currency);
            amount.setTotal(String.format("%.2f", total));
    
            Transaction transaction = new Transaction();
            transaction.setDescription(description);
            transaction.setAmount(amount);
    
            List<Transaction> transactions = new ArrayList<>();
            transactions.add(transaction);
    
            Payer payer = new Payer();
            payer.setPaymentMethod(method.toString());
    
            Payment payment = new Payment();
            payment.setIntent(intent.toString());
            payment.setPayer(payer);
            payment.setTransactions(transactions);
            RedirectUrls redirectUrls = new RedirectUrls();
            redirectUrls.setCancelUrl(cancelUrl);
            redirectUrls.setReturnUrl(successUrl);
            payment.setRedirectUrls(redirectUrls);
    
            return payment.create(apiContext);
        }
    
        public Payment executePayment(String paymentId, String payerId) throws PayPalRESTException{
            Payment payment = new Payment();
            payment.setId(paymentId);
            PaymentExecution paymentExecute = new PaymentExecution();
            paymentExecute.setPayerId(payerId);
            return payment.execute(apiContext, paymentExecute);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68



    (7)URLUtils.java

    package com.masasdani.paypal.util;
    
    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();
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25



    (8)cancel.html

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8" />
    <title>Insert title here</title>
    </head>
    <body>
        <h1>Canceled by user</h1>
    </body>
    </html>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10



    (9)index.html

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8" />
    <title>Insert title here</title>
    </head>
    <body>
    <form method="post" th:action="@{/pay}">
        <button type="submit"><img src="images/paypal.jpg" width="100px;" height="30px;"/></button>
    </form>
    </body>
    </html>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12



    (10)success.html

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8" />
    <title>Insert title here</title>
    </head>
    <body>
        <h1>Payment Success</h1>
    </body>
    </html>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10



    (11)最重要的!application.properties,paypal.client.app是App的CilentID, paypal.client.secret是Secret

    server.port: 8088
    spring.thymeleaf.cache=false
    
    paypal.mode=sandbox
    paypal.client.app=AeVqmY_pxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxKYniPwzfL1jGR
    paypal.client.secret=ELibZhExxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxUsWOA_-
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6


    • 测试


      (1)启动项目

    这里写图片描述

    (2)在浏览器输入localhost:8088

    这里写图片描述

    (3)点击paypal后,会跳到paypal的登录界面,登录测试账号(PRESONAL)后点击继续即可扣费,扣500$(具体数额可在controller中自定义)

    Payment payment = paypalService.createPayment(
                        500.00, 
                        "USD", 
                        PaypalPaymentMethod.paypal, 
                        PaypalPaymentIntent.sale,
                        "payment description", 
                        cancelUrl, 
                        successUrl);
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8



    这里写图片描述

    这里写图片描述

    (4)到https://www.sandbox.paypal.com 登录测试账号看看余额有没有变化



    这里写图片描述


    • 后言

  • 相关阅读:
    Echarts图表 相关技术点
    Jquery off() on() data()
    Js 正则表达式
    Java jar项目获取配置文件的项
    Java String.split 的坑,会忽略空值
    C# 工作流 状态机 门控制
    二维码SDK,高效率,高识别率,甩zxing,zbar几条街
    C#文本转语音,可导出在本地mp3或者wav文件
    api接口签名验证(MD5)
    C# 站点IP访问频率限制 针对单个站点的实现方法
  • 原文地址:https://www.cnblogs.com/jpfss/p/9945845.html
Copyright © 2020-2023  润新知