jfinal整合IJPay paypal支付

news2024/11/25 5:02:17

这里写目录标题

  • 环境准备
    • 1.注册paypal账户
    • 2.登录开发者中心
    • 3.创建沙箱账户
    • 4.在沙箱模式创建一个app,平台默认创建好了一个
      • 4.1填写信息
      • 4.2绑定某个沙箱账号
      • 4.3Client ID及Secret
  • 支付代码
    • 1.pom
    • 2.实例化配置
    • 3.支付订单
      • 3.1用sandbox的personal的账号登录,并支付
    • 4.支付成功&失败
    • 5.退款

环境准备

1.注册paypal账户

PayPal官方

在这里插入图片描述

2.登录开发者中心

PayPal开发者中心
在这里插入图片描述

3.创建沙箱账户

Business为收款账号,Personal为付款账号,平台默认创建好了两个账号
在这里插入图片描述
在这里插入图片描述
这里显示的 账户和密码,支付的时候用
在这里插入图片描述

4.在沙箱模式创建一个app,平台默认创建好了一个

在这里插入图片描述

4.1填写信息

类型:

Merchant-仅为自己收款

Platform-作为平台收款,可分账给卖家

4.2绑定某个沙箱账号

在这里插入图片描述

4.3Client ID及Secret

进入app详细页面,查看Client ID及Secret(后续需填写到代码中)

在这里插入图片描述

支付代码

1.pom

 <dependency>
            <groupId>com.github.javen205</groupId>
            <artifactId>IJPay-All</artifactId>
            <version>2.9.3</version>
        </dependency>

2.实例化配置

public PayPalApiConfig getConfig() {
    PayPalApiConfig config = new PayPalApiConfig();
    config.setClientId(payPalBean.getClientId());
    config.setClientSecret(payPalBean.getSecret());
    config.setSandBox(payPalBean.getSandBox());
    config.setDomain(payPalBean.getDomain());
    PayPalApiConfigKit.setThreadLocalApiConfig(config);
    return config;
}

3.支付订单

 private final static String RETURN_URL = "/center/pay/order/successUrl";
    private final static String CANCEL_URL = "/center/pay/order/cancelUrl";
/**
     * @return void
     * @params []
     * @Author
     * @Date
     * @Description: 支付订单
     */

    public void index() {
        String id = get("id");
        if (StrKit.isBlank(id)) {
            //re("订单id未提供");
            return;
        }
        BusOrder target = BusOrder.dao.template("order.find", Kv.by("id", id)).findFirst();
        if (target == null) {
            //re("订单不存在");
            return;
        }
        String pay_method = target.getPayMethod();
        try {
            PayPalApiConfig config = getConfig();

            //参数请求参数文档 https://developer.paypal.com/docs/api/orders/v2/#orders_create
            Map<String, Object> dataMap = new HashMap<>();
            dataMap.put("intent", "CAPTURE");//不改


            ArrayList<Map<String, Object>> list = new ArrayList<>();
            Map<String, Object> amount = new HashMap<>();
            amount.put("currency_code", "USD");//美元
            double actualPrice = NumberUtil.mul(target.getActualPrice() + "", "1").doubleValue();
            amount.put("value", actualPrice);//实际付款


            Map<String, Object> itemMap = new HashMap<>();
            itemMap.put("amount", amount);
            list.add(itemMap);
            dataMap.put("purchase_units", list);

            Map<String, String> applicationContext = new HashMap<>();
            applicationContext.put("cancel_url", config.getDomain().concat(CANCEL_URL) + "?id=" + target.getId() + "&user=" + getHeader("userCode"));//失败跳转地址
            applicationContext.put("return_url", config.getDomain().concat(RETURN_URL));//成功后跳转地址
            applicationContext.put("brand_name", "test");//品牌名称
            //applicationContext.put("logo_url", "");//付款方式徽标的 URL
            dataMap.put("application_context", applicationContext);

            String data = JSONUtil.toJsonStr(dataMap);
            log.info(data);
            IJPayHttpResponse resData = PayPalApi.createOrder(config, data);
            log.info(resData.toString());
            if (resData.getStatus() == 201) {
                String resultStr = resData.getBody();
                cn.hutool.json.JSONObject jsonObject = JSONUtil.parseObj(resultStr);
                //System.out.println(jsonObject);
                target.setOrderThirdId(jsonObject.getStr("id"));
                target.update();

                JSONArray links = jsonObject.getJSONArray("links");
                for (int i = 0; i < links.size(); i++) {
                    JSONObject item = links.getJSONObject(i);
                    String rel = item.getStr("rel");
                    String href = item.getStr("href");
                    if ("approve".equalsIgnoreCase(rel)) {
                        // redirect(href);
                        rsPara("支付地址获取成功", Kv.by("href", href));//支付地址 提交给前端
                        return;
                    }
                }
            }
            re("支付失败");
            return;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
  

3.1用sandbox的personal的账号登录,并支付

在这里插入图片描述

4.支付成功&失败

 //支付成功
    public void successUrl() {
        getPageStore("orderResult");
        String token = get("token");
        String payerId = get("PayerID");
        BusOrder target = BusOrder.dao.template("order.find", Kv.by("order_third_id", token)).findFirst();
        //确认付款
        log.info("token:" + token);
        log.info("payerId:" + payerId);
        PayPalApiConfig config = getConfig();
        IJPayHttpResponse response = PayPalApi.captureOrder(config, token, "");
        com.alibaba.fastjson.JSONObject jsonObject = com.alibaba.fastjson.JSONObject.parseObject(response.getBody());
        if (response.getStatus() == 201 && jsonObject.getString("status").equals("COMPLETED")) {
            target.setPayTime(DateUtil.now());
            target.setCallbackJson(response.getBody());
            target.setState("2");
            target.update();
                rs("支付成功,跳转页面");
                redirect(config.getDomain() + "/center/order/getOrders");
               return;
        }

        setAttr("status", response.getStatus());
        render("/order/result.html");
    }

    //未支付 返回
    public void cancelUrl() {
        //String readData = HttpKit.readData(getRequest());
       /* System.out.println(readData);
        rs(readData);*/
        // PayPalApiConfig config = getConfig();
        String userCode = get("user");
        BusUser log_user = Redis.use().get(RedisHeader.USER_LOGIN_CODE + userCode);
        if (log_user == null) {
            //re("");
            render("/");
            return;
        }
        String id = get("id");
        BusOrder target = BusOrder.dao.template("order.find", Kv.by("id", id)).findFirst();
        /*String token = get("token");
        BusOrder target = BusOrder.dao.template("order.find", Kv.by("order_third_id", token)).findFirst();*/
        setAttr("orderObj", target);
        getPageStore("orderDetail");
        render("/order/order_detail.html");
    }

5.退款

/**
     * @return void
     * @params []
     * @Author
     * @Date
     * @Description: 退款订单
     */
    public void refund() {
        com.alibaba.fastjson.JSONObject obj = getAttr("obj");
        String id = obj.getString("id");
        String refund_note = obj.getString("refund_note");

        BusOrder target = BusOrder.dao.template("order.find", Kv.by("id", id)).findFirst();
        if (target == null) {
            re("订单不存在");
            return;
        }
        try {
            com.alibaba.fastjson.JSONObject callbackJson = com.alibaba.fastjson.JSONObject.parseObject(target.getCallbackJson());//支付的时候给的json
            String captureId = callbackJson.getJSONArray("purchase_units").getJSONObject(0).getJSONObject("payments")
                    .getJSONArray("captures").getJSONObject(0).getString("id");

            PayPalApiConfig config = getConfig();
            Map<String, Object> map = new HashMap<>();
            String invoice_id = PayKit.generateStr();
            map.put("invoice_id", invoice_id);//退款编号
            map.put("note_to_payer", refund_note);//退款原因

            Map<String, String> amount = new HashMap<>();
            double v = NumberUtil.mul(target.getActualPrice() + "", "1").doubleValue();
            amount.put("value", v + "");
            amount.put("currency_code", "USD");

            map.put("amount", amount);

            String data = JSONUtil.toJsonStr(map);
            log.info("refund data:" + data);
            IJPayHttpResponse response = PayPalApi.refund(config, captureId, data);
            log.info(response.toString());
            if (response.getStatus() == 201) {
                target.setRefundTime(DateUtil.now());
                target.setState("5");
                target.setRefundNote(refund_note);
                target.setRefundInvoice(invoice_id);
                target.update();
                rs("Refund success");
                //redirect(config.getDomain() + "/center/order/getOrders");
                return;
            } else {
                re("Refund failure ");
            }
            return;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/90700.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

你说精通MySQL其实很菜jī(1):你不一定会的基本技巧或知识点(值得一看)

你说精通MySQL其实很菜jī&#xff08;1&#xff09;&#xff1a;你不一定会的基本技巧或知识点&#xff08;值得一看&#xff09;《你说精通MySQL其实很菜jī》系列文章&#xff08;持续更新&#xff09;一、前言二、技巧或知识点汇总1、MySQL客户端&#xff08;Client&#x…

HID设备的报告描述符

HID设备类定义文档中明确指出&#xff0c;一个报告描述符必须包含但不仅限于以下数据项&#xff1a; 输入&#xff08;输出或特征&#xff09; 指明了报告的类型&#xff0c;其中隐含了报告的传输方向以及报告数据所具有的数学特性。 用法&#xff08;也可用“用法最小值与最大…

发现oracle10gSYSAUX空间没有了进行处理

今天用户反馈sap有些因为有问题&#xff0c;所以寻找一下原因&#xff1a; 1、用db02看空间情况 看这里好像空间是没有了&#xff0c;99%使用掉了 2、用toad看空间也是类型情况&#xff0c;所以确实这个表空间没有了 3、检查SYSAUX项目空间占比 SELECT occupant_name"…

Spring Boot 3.x微服务升级经历

前言 Spring Boot 3.0.0 GA版已经发布&#xff0c;好多人也开始尝试升级&#xff0c;有人测试升级后&#xff0c;启动速度确实快了不少&#xff0c;如下为网络截图&#xff0c;于是我也按捺不住的想尝试下。 历程 首先就是要把Spring Boot、Spring Cloud 相关的依赖升一下 …

用Python画一棵分形树

文章目录画一棵分形树加入随机量的分形树加入点缀的圣诞树画一棵分形树 分形树&#xff0c;就是用分形的逻辑去画一棵树&#xff0c;所谓分形&#xff0c;若从编程的角度去理解&#xff0c;其实就是简单规则的反复迭代。 例如&#xff0c;现在有一条线段&#xff0c;长为LLL&…

【微服务远程调用】基于RestTemplate发送HTTP请求实现微服务远程调用

本期目录1. 情景2. 远程调用方式分析3. 远程调用步骤3.1 注册 RestTemplate3.2 修改订单业务层3.3 测试4. 总结1. 情景 我编写的订单微服务查询订单时&#xff0c;无法跨越数据库查询订单所关联的用户 user 。因此下图中订单数据的 user 字段为 null 。 本节&#xff0c;我们…

【LSS: Lift, Splat, Shoot】代码的复现与详细解读

文章目录一、代码复现1.1 环境搭建1.2 数据集下载1.3 Evaluate a model1.4 Visualize Predictions1.5 Visualize Input/Output Data1.6 Train a model二、代码理解main.pyexplore.pydata.pymodels.pytools.pytrain.py原论文&#xff1a;https://arxiv.org/pdf/2008.05711v1.pdf…

Charles下载安装与手机调试教程

Charles下载与安装教程 1、安装目的&#xff1a;Charles需要收费&#xff0c;fiddler工具免费&#xff0c;想对比一下Charles抓包和fiddler抓包的异同 2、官网下载 https://www.charlesproxy.com/latest-release/download.do 3、选择合适的版本进行安装 ----------以下内容有参…

PyQt5 QtChart-曲线图

PyQt5 QtChart-QSplineSeries曲线图QSplineSeriesQSplineSeries QSplineSeries类将数据序列显示为曲线图。核心代码: spline QSplineSeries() spline.append(0, 23) spline.append(1, 56) … chart.addSeries(lineSeries) 常用方法&#xff1a; setPointsVisible(True) &am…

[附源码]Python计算机毕业设计高校教室管理系统Django(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等…

Stm32旧版库函数11——串口发送数据 使用中断接收

#include "stm32f10x_lib.h" #include "usart.h" #include "delay.h" /* ******************************************************************************** ** 函数名称 &#xff1a; USART1_Configuration(void) ** 函数功能 &#xff1a;…

城市消费券之地理位置攻防

近期&#xff0c;顶象发布了《城市消费券安全调研报告》&#xff08;以下简称《调研报告》&#xff09;。《调研报告》从城市消费券的发放规模、核销情况、风险出发&#xff0c;进一步分析除了黑灰产的作弊手段以及作弊工具。 其就作弊手段而言&#xff0c;黑灰产哄抢城市消费…

软件工程毕业设计题目100例

文章目录0 简介1 如何选题2 最新软件工程毕设选题3 最后0 简介 学长搜集分享最新的软件工程业专业毕设选题&#xff0c;难度适中&#xff0c;适合作为毕业设计&#xff0c;大家参考。 学长整理的题目标准&#xff1a; 相对容易工作量达标题目新颖 1 如何选题 最近非常多的学…

3个条件,筛选出最趁手的财务分析工具

市面上的财务分析工具很多&#xff0c;但究竟哪一种更好用&#xff0c;更趁手&#xff1f;这就需要看哪个财务分析工具可做到以下3大要求。 1&#xff1a;是否能快速计算财务分析指标 在财务分析中&#xff0c;存在一个需要在行与行之间进行计算分析需求&#xff0c;比如在利…

[附源码]Python计算机毕业设计高校教室申请管理系统Django(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等…

网络原理 一

网络原理 本文主要是介绍TCP/IP协议这里面的核心内容,还是很重要的 TCP/IP协议的层级 应用层 传输的数据如何去使用 传输层 起点和终点的传输 网络层 中间传输过程中的路径规划 数据链路层 相邻节点的传输 物理层 这是最底层的,相当于基础设施 应用层 不同的应用程序,涉及到…

「Electron|快速开始」来写个Hello World吧

本文主要介绍如何快速使用Electron生成一个Hello World应用 文章目录主要步骤一、准备工作创建项目安装electron二、编写electron应用所需的基本内容首先&#xff0c;我们需要给electron应用一个入口创建窗口往窗口里面放一个HTML界面&#xff0c;写上"Hello World!"…

修改ik分词器源码实现直连数据库动态增量更新词汇

谈到es的中文分词器,肯定少不了ik分词器.现ik分词器有两种获取主词汇和停用词的方法: 一是通过ik\config目录下的main.dic和stopword.dic获取,但是每次修改后要重启才能生效 二是通过提供接口返回所有词汇的接口,接口路径配置在.但是该方式每次都需要将所有词汇返回,效率不高.…

大数据课设

----------------------------------------------------------------------------------------------------------------------------- 由于本人主修嵌入式方向最多使用的就是C语言&#xff0c;由于物联网这个专业的特殊性&#xff0c;javaweb没少 写&#xff0c;所以java也用…

Nginx动静分离

&#x1f341;博客主页&#xff1a;&#x1f449;不会压弯的小飞侠 ✨欢迎关注&#xff1a;&#x1f449;点赞&#x1f44d;收藏⭐留言✒ ✨系列专栏&#xff1a;&#x1f449;Linux专栏 &#x1f525;欢迎大佬指正&#xff0c;一起学习&#xff01;一起加油&#xff01; 目录&…