java对接paypal支付基础实例(v1)

java对接paypal支付基础实例(v1)

1.环境准备

注册paypal账号
注册paypal开发者账号
创建两个测试用户
创建应用,生成用于测试的clientID 和 密钥

2.代码集成

springboot环境
pom引进paypal-sdk的jar包

注册paypal账号

在浏览器输入链接: https://www.paypal.com. 跳转到如下界面,点击右上角的注册
java对接paypal支付基础实例(v1)_第1张图片
java对接paypal支付基础实例(v1)_第2张图片

注册paypal开发者账号

在浏览器输入链接: https://developer.paypal.com,点击右上角的“Log into Dashboard”,用上一步创建好的账号登录
java对接paypal支付基础实例(v1)_第3张图片
创建两个测试用户

登录成功后,在左边的导航栏中点击 Sandbox 下的 Accounts
java对接paypal支付基础实例(v1)_第4张图片
点击右上角的“Create Account”,创建测试用户(商户账户和个人账户)
java对接paypal支付基础实例(v1)_第5张图片

用测试账号登录查看,登录测试网址(跟开发网址不是同一个):链接: https://www.sandbox.paypal.com 在这里登陆测试账户

创建APP
创建app目的 个人账户消费的目标是商户账号 点击create app

选择商户账号(商户为创建的商户并非登录的商户)
java对接paypal支付基础实例(v1)_第6张图片
测试环境为sanbox 线上以后需要在live创建app(商户为当前登录用户)
java对接paypal支付基础实例(v1)_第7张图片
点击刚刚创建好的App“TestApp”,注意看到”ClientID“ 和”Secret“(Secret如果没显示,点击下面的show就会看到,点击后show变为hide)
java对接paypal支付基础实例(v1)_第8张图片
java对接paypal支付基础实例(v1)_第9张图片
开始代码

项目层级显示
java对接paypal支付基础实例(v1)_第10张图片

引入依赖pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.0</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <!--paypal-->
        <dependency>
            <groupId>com.paypal.sdk</groupId>
            <artifactId>rest-api-sdk</artifactId>
            <version>1.4.2</version>
        </dependency>
        <dependency>
            <groupId>com.paypal.sdk</groupId>
            <artifactId>checkout-sdk</artifactId>
            <version>1.0.2</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- Swagger 接口文档 -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-log4j12</artifactId>
                </exclusion>
                <exclusion>
                    <artifactId>slf4j-api</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.7</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>


application.properties配置

#端口号
server.port= 8088
#html地址
spring.thymeleaf.prefix=classpath:/templates/
# 沙盒模式测试sanbox 线上模式改成live 
# paypal.client.app和paypal.client.secret请查看app配置
paypal.mode=sandbox
paypal.client.app=AYxj25IuPg4rAQbUmOZCSIEdmji***********VPWo74dqVUnW1q0_WUoVJr4MIeS95PKnYSNJd5W9KT
paypal.client.secret=EKcdUZKpu5XPEQiFFh85kFAe************6iLyhh4xm42tqBCCVKApqJ8QdVcd8XUxYY-0WD8i

Controller层

package com.example.demo.controller;

import com.example.demo.model.PaymentModel;
import com.example.demo.service.PaymentService;
import com.example.demo.until.URLUtils;
import com.paypal.api.payments.Links;
import com.paypal.api.payments.Payment;
import com.paypal.base.rest.PayPalRESTException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

/**
 * @program: 
 * @description:
 * @author: 
 * @create: 
 **/

@Controller
public class PaymentController {

    /**
     * 成功页面
     */
    public static final String PAYPAL_SUCCESS_URL = "pay/success";

    /**
     * 取消页面
     */
    public static final String PAYPAL_CANCEL_URL = "pay/cancel";

    @Resource
    private PaymentService paymentService;

    @GetMapping("/paypal")
    public String index(){
        return "index";
    }

    @PostMapping("/pay")
    public String payment(HttpServletRequest request){
        //获取取消页面
        String cancelUrl = URLUtils.getBaseURl(request) + "/" + PAYPAL_CANCEL_URL;
        //获取成功页面
        String successUrl = URLUtils.getBaseURl(request) + "/" + PAYPAL_SUCCESS_URL;
        Payment payment = null;
        PaymentModel paymentModel = new PaymentModel();
        //金额
        paymentModel.setAmount("10");
        //金额类型
        paymentModel.setCurrency("USD");
        //充值描述
        paymentModel.setDescription("payment description");
        try {
            payment = paymentService.createPayment(paymentModel, cancelUrl, successUrl);
        } catch (PayPalRESTException e) {
            e.printStackTrace();
        }
        for(Links links : payment.getLinks()){
            if(links.getRel().equals("approval_url")){
                //客户付款登陆地址
                return "redirect:" + links.getHref();
            }
        }
        return "redirect:/";
    }

    /**
     * 取消页面
     * @return
     */
    @GetMapping(value = PAYPAL_CANCEL_URL)
    public String cancelPay(){
        return "cancel";
    }

    /**
     * 执行支付
     * @param paymentId
     * @param payerId
     * @return
     */
    @GetMapping(value = PAYPAL_SUCCESS_URL)
    public String successPay(@RequestParam("paymentId") String paymentId, @RequestParam("PayerID") String payerId){
        Payment payment = null;
        try {
            payment = paymentService.executePayment(paymentId, payerId);
        } catch (PayPalRESTException e) {
            e.printStackTrace();
        }
        if(payment.getState().equals("approved")){
            return "success";
        }
        return "redirect:/";
    }
}

service层

package com.example.demo.service;

import com.example.demo.model.PaymentModel;
import com.paypal.api.payments.Payment;
import com.paypal.base.rest.PayPalRESTException;

/**
 * @program: 
 * @description:
 * @author: 
 * @create: 
 **/
public interface PaymentService {

    /**
     * 创建支付
     * @param paymentModel
     * @param cancelUrl
     * @param successUrl
     * @return
     * @throws PayPalRESTException
     */
    Payment createPayment(PaymentModel paymentModel, String cancelUrl, String successUrl) throws PayPalRESTException;

    /**
     * 执行支付
     * @param paymentId
     * @param payerId
     * @return
     * @throws PayPalRESTException
     */
    Payment executePayment(String paymentId, String payerId) throws PayPalRESTException;
}

Impl层

package com.example.demo.impl;

import com.example.demo.config.PaypalPaymentIntent;
import com.example.demo.config.PaypalPaymentMethod;
import com.example.demo.model.PaymentModel;
import com.example.demo.service.PaymentService;
import com.paypal.api.payments.*;
import com.paypal.base.rest.APIContext;
import com.paypal.base.rest.PayPalRESTException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @program: 
 * @description:
 * @author: 
 * @create: 
 **/
@Service
public class PaymentServiceImpl implements PaymentService {

    private final APIContext apiContext;

    private final String USD = "USD";

    @Autowired
    public PaymentServiceImpl(APIContext apiContext) {
        this.apiContext = apiContext;
    }

    @Override
    public Payment createPayment(PaymentModel paymentModel , String cancelUrl, String successUrl) throws PayPalRESTException {
        //订单金额 以及金额类型 默认为USD
        Amount amount = new Amount();
        if(null!=paymentModel.getCurrency()){
            amount.setCurrency(paymentModel.getCurrency());
        }else{
            amount.setCurrency(USD);
        }
        amount.setTotal(paymentModel.getAmount());

        List<Transaction> transactions = new ArrayList<>();
        Transaction transaction = new Transaction();
        transaction.setDescription(paymentModel.getDescription());
        transaction.setAmount(amount);
        transactions.add(transaction);

        /**
         * 支付信息
         */
        Payer payer = new Payer();
        payer.setPaymentMethod(PaypalPaymentMethod.paypal.toString());
        Payment payment = new Payment();
        payment.setIntent(PaypalPaymentIntent.sale.toString());
        payment.setPayer(payer);
        payment.setTransactions(transactions);
        /**
         * 回调地址
         */
        RedirectUrls redirectUrls = new RedirectUrls();
        redirectUrls.setCancelUrl(cancelUrl);
        redirectUrls.setReturnUrl(successUrl);
        payment.setRedirectUrls(redirectUrls);
        return payment.create(apiContext);
    }

    @Override
    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);
    }
}

config类

package com.example.demo.config;

import com.paypal.base.rest.APIContext;
import com.paypal.base.rest.OAuthTokenCredential;
import com.paypal.base.rest.PayPalRESTException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
 * @program: 
 * @description:
 * @author: 
 * @create: 
 **/
@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;
    }
}

package com.example.demo.config;

/**
 * @program:
 * @description:
 * @author: 
 * @create: 
 **/
public enum PaypalPaymentIntent {

    sale, authorize, order
}

package com.example.demo.config;

/**
 * @program: 
 * @description:
 * @author: 
 * @create: 
 **/
public enum PaypalPaymentMethod {

    credit_card, paypal

}

spingboot启动类

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

/**
 * @program: 
 * @description:
 * @author: 
 * @create: 
 **/
@EnableAutoConfiguration
@Configuration
@ComponentScan
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

paypal图标 paypal.jsp
java对接paypal支付基础实例(v1)_第11张图片成功 取消 登录界面html
index.html


<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
head>
<body>
<form method="post" th:action="@{/pay}">
    <button type="submit"><img src="images/paypal.jpg" width="100px;" height="30px;"/>button>
form>
body>
html>

success.html


<html>
<head>
    <meta charset="UTF-8" />
    <title>Insert title heretitle>
head>
<body>
<h1>Payment Successh1>
body>
html>

cancel.html


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
head>
<body>
    <h1>Canceled by userh1>
body>
html>

启动登录
java对接paypal支付基础实例(v1)_第12张图片
登录账号(之前注册的个人账号Test-P)
java对接paypal支付基础实例(v1)_第13张图片
java对接paypal支付基础实例(v1)_第14张图片
到链接: https://www.sandbox.paypal.com. 登录测试账号看看余额有没有变化
java对接paypal支付基础实例(v1)_第15张图片

java对接paypal支付基础实例(v1)_第16张图片

实际开发中 可以参照本博客V2版本链接: https://blog.csdn.net/m0_37693638/article/details/111152268.

你可能感兴趣的:(java)