完整版PayPal支付(java后端教程)

首先引入 PayPal的sdk 这里我引入的是1.0.4版本的

            <!-- 贝宝支付  SDK   --><dependency><groupId>com.paypal.sdk</groupId><artifactId>checkout-sdk</artifactId><paypal-sdk.version>1.0.4</paypal-sdk.version></dependency>

yml文件引入公司在官网的相关配置
这里我做了yml的文件环境隔离,限免的配置做了示例

  #  贝宝支付的测试服
pay:  paypal:clientId: AeEX1PNMNaP3RuV8JTBMznAhs_gOfFwloG6SG3TiQh1_MBj0clientSecret: EMDda7g_Q7KmOiH08qJfg-dAb8d2THkYtzRR#测试的modemode: sandbox#正式的modemode: live
/*** @since 2.0.0*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@ApiModel
public class PayPalVo extends RequestModel {/**  本站订单号 */@ApiModelProperty(value = "本站订单号")private String orderNo;/**  三方订单号 */@ApiModelProperty(value = "本站订单号")private String outOrderNo;/** 1 书币充值 ; 2 plus会员充值;3 premium会员充值 */@ApiModelProperty(value = "1 书币充值 ; 2 plus会员充值;3 premium会员充值")private Integer orderType;
}
PayPal支付
```java/*** 贝宝支付** @param payPalVo 请求对象* @return 返回结果*/@PostMapping("/payPalNotify")@ApiOperation(value = "贝宝支付二次验证")@Deprecatedpublic ResponseModel<PayOrderDto> payPalNotify(@RequestBody PayPalVo payPalVo){if (ObjectUtils.isEmpty(payPalVo.getOrderNo()) || ObjectUtils.isEmpty(payPalVo.getOutOrderNo()) || ObjectUtils.isEmpty(payPalVo.getOrderType())){return ResponseModel.error(appConfigStatusCodeService.getStatusCode(payPalVo.getLanguage(), ResponseCnSate.PARAM_EXCEPTION));}// 根据paypal的订单id,捕获订单付款String outOrderNo = payPalVo.getOutOrderNo();String orderNo = payPalVo.getOrderNo();Integer orderType = payPalVo.getOrderType();// 校验该订单是否处理if (payOrderService.isDispose(orderNo) == PayConstants.ORDER_IS_DISPOSE) {return ResponseModel.error(appConfigStatusCodeService.getStatusCode(payPalVo.getLanguage(), ResponseCnSate.ORDER_PROCESSED));}//进行二次验证Boolean pay = payPalUtils.verifyOrderInfo(outOrderNo);//如果成功则执行后面的逻辑if (pay){boolean b = orderService.finishOrder(orderNo, orderType,payPalVo.getLanguage());if (!b){return ResponseModel.error(appConfigStatusCodeService.getStatusCode(payPalVo.getLanguage(), ResponseCnSate.ORDER_HANDLER_FAIL));}//保存订单号返回订单信息PayOrderDto payOrderDto =orderService.saveAndGetOrderInfo(payPalVo.getUserId(),outOrderNo,orderNo);if (ObjectUtils.isNotEmpty(payOrderDto)){return ResponseModel.success(payOrderDto);}return ResponseModel.error(appConfigStatusCodeService.getStatusCode(payPalVo.getLanguage(), ResponseCnSate.RETURN_ORDER_INFO_FAIL));}//失败返回提示return ResponseModel.error(appConfigStatusCodeService.getStatusCode(payPalVo.getLanguage(), ResponseCnSate.AUTH_FAIL_TWO));}

后面为了让大家都看的明白 我单独抽取了一个工具,简单的做了描述

package com.wyzz.global.untils.paypal;import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;import com.paypal.core.PayPalEnvironment;
import com.paypal.core.PayPalHttpClient;
import com.paypal.http.HttpResponse;
import com.paypal.http.serializer.Json;
import com.paypal.orders.*;
import com.paypal.payments.CapturesGetRequest;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;/*** PayPal工具类** @since 2.0.0*/
@Service
@Slf4j
public class PayPalUtils {/*** paypal配置应用的客户端ID*/@Value("${pay.paypal.clientId}")private String clientId;/*** paypal配置应用的客户端密钥*/@Value("${pay.paypal.clientSecret}")private String clientSecret;/*** paypal连接环境:live表示生产,sandbox表示沙盒*/@Value("${pay.paypal.mode}")private String mode;/*** paypal的http客户端* @param mode 环境信息* @param clientId 客户端ID* @param clientSecret 密钥* @return*/public PayPalHttpClient client(String mode, String clientId, String clientSecret) {log.info("mode={}, clientId={}, clientSecret={}", mode, clientId, clientSecret);PayPalEnvironment environment = mode.equals("live") ? new PayPalEnvironment.Live(clientId, clientSecret) : new PayPalEnvironment.Sandbox(clientId, clientSecret);return new PayPalHttpClient(environment);}/*** 构建订单请求体* @return*/public OrderRequest buildRequestBody() {return new OrderRequest();}/*** 校验订单信息:先扣款,后查询订单详情* @param orderId 前端提供的palpay的订单id* @return 订单存在并已扣款成功返回true*/public Boolean verifyOrderInfo(String orderId) {Boolean f = false;try {// 1.用户授权支付成功,进行扣款操作this.captureOrder(orderId);} catch (Exception e) {e.printStackTrace();} finally {// 2.扣款操作失败时也要查询订单,确认是否已扣款try {OrdersGetRequest request = new OrdersGetRequest(orderId);HttpResponse<Order> response = client(mode, clientId, clientSecret).execute(request);System.out.println("Status Code: " + response.statusCode());System.out.println("Status: " + response.result().status());System.out.println("Order id: " + response.result().id());if(response.result().purchaseUnits().get(0).payments() != null) {List<Capture> captures = response.result().purchaseUnits().get(0).payments().captures();if(captures != null) {for (Capture capture : captures) {if (capture.id() != null && capture.id().length() > 0) {f = true;}}}}} catch (Exception e2) {e2.printStackTrace();}}return f;}/*** 用户授权支付成功,进行扣款操作:* 用户通过CreateOrder生成 approveUrl 跳转paypal支付成功后,只是授权,并没有将用户的钱打入我们的paypal账户,我们需要通过 CaptureOrder接口,将钱打入我的PayPal账户* @param orderId 前端提供的palpay的订单id*/public void captureOrder(String orderId){OrdersCaptureRequest request = new OrdersCaptureRequest(orderId);request.requestBody(this.buildRequestBody());HttpResponse<Order> response = null;try {response = client(mode, clientId, clientSecret).execute(request);} catch (IOException e1) {try {log.error("第1次调用paypal扣款失败");response = client(mode, clientId, clientSecret).execute(request);} catch (Exception e) {try {log.error("第2次调用paypal扣款失败");response = client(mode, clientId, clientSecret).execute(request);} catch (Exception e2) {log.error("第3次调用paypal扣款失败,失败原因 {}", e2.getMessage() );}}}if (ObjectUtils.isNotEmpty(response)) {log.info("Status Code = {}, Status = {}, OrderID = {}", response.statusCode(), response.result().status(), response.result().id());for (LinkDescription link : response.result().links()) {log.info("Links-{}: {}    \tCall Type: {}", link.rel(), link.href(), link.method());}for (PurchaseUnit purchaseUnit : response.result().purchaseUnits()) {for (Capture capture : purchaseUnit.payments().captures()) {log.info("Capture id: {}", capture.id());log.info("status: {}", capture.status());log.info("invoice_id: {}", capture.invoiceId());if("COMPLETED".equals(capture.status())) {//进行数据库操作,修改订单状态为已支付成功,尽快发货(配合回调和CapturesGet查询确定成功)log.info("支付成功,状态为=COMPLETED");}if("PENDING".equals(capture.status())) {log.info("status_details: {}", capture.captureStatusDetails().reason());String reason = "PENDING";if(capture.captureStatusDetails() != null && capture.captureStatusDetails().reason() != null) {reason = capture.captureStatusDetails().reason();}//进行数据库操作,修改订单状态为已支付成功,但触发了人工审核,请审核通过后再发货(配合回调和CapturesGet查询确定成功)log.info("支付成功,状态为=PENDING : {}", reason);}}}Payer buyer = response.result().payer();log.info("Buyer Email Address: {}", buyer.email());log.info("Buyer Name: {} {}", buyer.name().givenName(), buyer.name().surname());}}/*** 查询订单详情* @param orderId 前端提供的palpay的订单id* @throws IOException*/public void ordersGetRequest(String orderId) throws IOException {OrdersGetRequest request = new OrdersGetRequest(orderId);HttpResponse<Order> response = null;try {response = client(mode, clientId, clientSecret).execute(request);} catch (Exception e) {try {System.out.println("调用paypal订单查询失败,链接异常1");response = client(mode, clientId, clientSecret).execute(request);} catch (Exception e2) {try {System.out.println("调用paypal订单查询失败,链接异常2");response = client(mode, clientId, clientSecret).execute(request);} catch (Exception e3) {System.out.println("调用paypal订单查询失败,链接异常3");System.out.println(e3.getMessage());}}}System.out.println("Status Code: " + response.statusCode());System.out.println("Status: " + response.result().status());System.out.println("Order id: " + response.result().id());if(response.result().purchaseUnits().get(0).payments() != null) {List<Capture> captures = response.result().purchaseUnits().get(0).payments().captures();if(captures != null) {for (Capture capture : captures) {System.out.println("\t订单编号= " + capture.invoiceId() + "\tCapture Id= " + capture.id() + "\tCapture status= " + capture.status() + "\tCapture amount= " + capture.amount().currencyCode() + ":" + capture.amount().value());}}List<Refund> refunds = response.result().purchaseUnits().get(0).payments().refunds();if(refunds != null) {for (Refund refund : refunds) {System.out.println("\t售后编号= " + refund.invoiceId() + "\tRefund Id= " + refund.id() + "\tRefund status= " + refund.status() + "\tRefund amount= " + refund.amount().currencyCode() + ":" + refund.amount().value());}}}System.out.println("Links: ");for (LinkDescription link : response.result().links()) {System.out.println("\t" + link.rel() + ": " + link.href() + "\tCall Type: " + link.method());}}/*** 查询扣款详情* @param orderId 前端提供的palpay的订单id* @throws IOException*/public void capturesGetRequest(String orderId) throws IOException {CapturesGetRequest request = new CapturesGetRequest(orderId);HttpResponse<com.paypal.payments.Capture> response = client(mode, clientId, clientSecret).execute(request);System.out.println("Status Code: " + response.statusCode());System.out.println("Status: " + response.result().status());System.out.println("Capture ids: " + response.result().id());System.out.println("Links: ");for (com.paypal.payments.LinkDescription link : response.result().links()) {System.out.println("\t" + link.rel() + ": " + link.href() + "\tCall Type: " + link.method());}}public Map<String,Object> createOrder(OrderRequest orderRequest) {OrdersCreateRequest request = new OrdersCreateRequest();request.header("prefer","return=representation");request.requestBody(orderRequest);
//        PayPalClient payPalClient = new PayPalClient();HttpResponse<Order> response = null;try {response = client(mode, clientId, clientSecret).execute(request);} catch (IOException e1) {try {log.error("第1次调用paypal订单创建失败");response = client(mode, clientId, clientSecret).execute(request);} catch (Exception e) {try {log.error("第2次调用paypal订单创建失败");response = client(mode, clientId, clientSecret).execute(request);} catch (Exception e2) {log.error("第3次调用paypal订单创建失败,失败原因:{}", e2.getMessage());}}}
//        String approve = "";Map<String,Object> map = new HashMap();if (response.statusCode() == 201) {log.info("Status Code = {}, Status = {}, OrderID = {}, Intent = {}", response.statusCode(), response.result().status(), response.result().id(), response.result().checkoutPaymentIntent());map.put("Id",response.result().id());for (LinkDescription link : response.result().links()) {log.info("Links-{}: {}    \tCall Type: {}", link.rel(), link.href(), link.method());if(link.rel().equals("approve")) {
//                    approve = link.href();map.put("outOrderNo",link.href());}}String totalAmount = response.result().purchaseUnits().get(0).amountWithBreakdown().currencyCode() + ":" + response.result().purchaseUnits().get(0).amountWithBreakdown().value();log.info("Total Amount: {}", totalAmount);
//            String json= new JSONObject(new Json().serialize(response.result())).toString(4);
//            log.info("createOrder response body: {}", json);}return map;}//    public static void main(String[] args) throws Exception {
//        PayPalUtils payPalUtils = new PayPalUtils();
//        payPalUtils.verifyOrderInfo("45S82276S8854414K");
//        payPalUtils.ordersGetRequest("45S82276S8854414K");
//        payPalUtils.captureOrder("18K07174PX6483500");
//        payPalUtils.capturesGetRequest("31V65486WC667442G");
//        // issue : ORDER_ALREADY_CAPTURED 订单已被捕获
//        // intent=CAPTURE 每个订单只允许捕获一次
//    }
}

不敢说描述的有多么到位 只希望给java将要对接paypal的同学一点儿参考

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

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

相关文章

mac玩rust用什么画质_Mac上的活动监视器到底有什么用?你会用么?

您希望当Mac卡住或沙滩球不断旋转时&#xff0c;Mac中有一个任务管理器。它允许您强制退出已冻结的网站或应用程序。Windows用户熟悉任务管理器&#xff0c;并且擅长使用它来管理PC任务以优化PC性能。因此&#xff0c;您想知道Mac上是否有任务管理器&#xff1f;是的&#xff0…

js 闭包

一、闭包的作用 实现公有变量 — 函数累加器可以做缓存&#xff08;存储结构&#xff09;可以实现封装&#xff0c;属性私有化模块化开发&#xff0c;防止污染全局变量 闭包实现 1 … 100 function add() {var count 0;function demo() {count;console.log(count);}retur…

java实现 支付宝支付

文章目录支付宝开放平台官网创建demo实例分析效果图实例代码AlipayConfigPaymentControllerOrderService OrderServiceImplapplicationContext-alipay.xml支付宝开放平台官网 用自己手机支付宝扫码登录 根据页面提示填写自己真实信息 进去之后 东西主要用的就在这里 sdk 在 …

python读取git日志_Python获取gitlab提交历史!

工作中的场景&#xff0c;记录下来分享给大家。需求公司私有部署了gitlab保存公司代码&#xff0c;希望在发布系统中可以展示项目在gitlab的提交历史&#xff0c;供发布人员选择提交commit记录并构建对应的docker镜像。不可行的方案但是很快我就发现&#xff0c;这个方案是不可…

js 对象和构造函数

一、对象的创建方法 题外话&#xff1a; java c 同样能生产出对象&#xff0c;但是是死的 JavaScript 生产出的对象是活的&#xff0c;更像是人的生长过程&#xff0c;后天可以增加和删除方法 用字面量创建 var obj {};二、对象的增删改 增 let obj {};obj.name 张三; …

Java接入支付宝支付教程

Java接入支付宝支付教程 一、创建应用 1.登录支付宝开放平台 支付宝开放平台网址&#xff1a;https://open.alipay.com/platform/developerIndex.htm 2.创建一个应用 ? 图1 二 、设置应用密钥 1.下载安装支付宝开放平台助手 软件下载地址&#xff1a;https://gw.alipay…

虚拟同步发电机_测量虚拟同步发电机惯量与阻尼系数的新方法

华北电力大学分布式储能与微网河北省重点实验室的研究人员颜湘武、王俣珂、贾焦心、王德胜、张波&#xff0c;在2019年第7期《电工技术学报》上撰文(论文标题为“基于非线性最小二乘曲线拟合的虚拟同步发电机惯量与阻尼系数测量方法”)指出&#xff0c;虚拟同步发电机(VSG)技术…

对象的包装类

一、首先抛出疑问&#xff1a; 原始值为啥添加属性而且不会报错 &#xff1f;&#xff1f;&#xff1f; var str a; str.name abc; console.log(str.name); // 就是因为原始值要经过包装类 var str abc; str.length 2; // new String(abc).length 2; delete console.lo…

expdp导出 schema_Oracle使用数据泵在异机之间导出导入多个 schema

需求&#xff1a;A机中的oracle有pingchuan和zte两个用户(schema)&#xff0c;这两个schema中都有数据。B机刚装完oracle数据库并建好实例&#xff0c;没有数据。A机的IP为192.168.1.131&#xff0c;B机的IP为192.168.1.137。要求把A机中的pingchuan和zte导入到B机中。(1)A机导…

SpringBoot整合阿里云OSS上传文件

一、需求分析 文件上传是一个非常常见的功能&#xff0c;就是通过IO流将文件写到另外一个地方&#xff0c;这个地方可以是项目下的某个文件夹里&#xff0c;或者是本地电脑某个盘下面&#xff0c;还可以是云服务OSS里面&#xff0c;这里就是我要讲到的OSS&#xff0c;我写的是…

js 原型以及原型链

原型编程的基本规则&#xff1a; 所有的数据都是对象要得到一个对象&#xff0c;不是通过实例化类&#xff0c;而是找到一个对象作为原型并克隆它对象会记住它的原型如果对象无法相应某个请求&#xff0c;它会把这个请求委托给它自己的原型 直接上图 一、继续说说构造函数 …

python tfidf特征变换_使用sklearn提取文本的tfidf特征

from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer, TfidfTransformercorpus [This is the first document.,This is the second second document.,And the third one.,Is this the first document?,]CountVectorizer是通过fit_transform函数将…

SpringBoot整合阿里云OSS文件上传、下载、查看、删除

SpringBoot整合阿里云OSS文件上传、下载、查看、删除 该项目源码地址&#xff1a;https://github.com/ggb2312/springboot-integration-examples &#xff08;其中包含SpringBoot和其他常用技术的整合&#xff0c;配套源码以及笔记。基于最新的 SpringBoot2.1&#xff0c;欢迎各…

js 继承发展史

一、传统模式 – 利用原型链 Grand.prototype.lastName 王五; function Grand() {} var grand new Grand();Father.prototype grand; function Father() {this.name 李四 } var father new Father();Son.prototype father; function Son() {} var son new Son(); conso…

vue 调用webservice_js跨域调用WebService的简单实例

步骤1. 在web.config中的system.web节点里加入步骤2.webservice代码using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.Services;using System.Web.Mvc;namespace WebService{/// /// WebService1 的摘要说明/// [WebServic…

SpringBoot整合oss实现文件的上传,查看,删除,下载

springboot整合oss实现文件的上传,查看,删除,下载 1.什么是对象存储 OSS? 答&#xff1a;阿里云对象存储服务&#xff08;Object Storage Service&#xff0c;简称 OSS&#xff09;&#xff0c;是阿里云提供的海量、安全、低成本、高可靠的云存储服务。其数据设计持久性不低…

属性的表示方法和对象的枚举

对象 一、对象.属性 var obj {name : mary,age : 18 };console.log(obj.name, obj.age); // mary 18二、对象[‘属性’] – 让对象属性更加灵活 var zhang {wife1: {name: xiaomei},wife2: {name: xiaoli},wife3: {name: xiaowang},wife4: {name: xiaoxiao},sayWife: funct…

docker 启动成功但无法访问_docker nginx 运行后无法访问的问题解决

## 1最近在学docker部署&#xff0c;一开始打算将nginx先docker化的。对照官方的docker镜像介绍说明&#xff0c;进行自定义配置将官方的nginx.conf复制出来后&#xff0c;修改添加了一些自定义&#xff0c;主要是屏蔽了default.conf&#xff0c;以及include文件夹 sites-avail…

minio实现文件上传下载和删除功能

前言 之前用到文件上传功能&#xff0c;在这里做个学习记录。使用minio实现&#xff0c;后面会记录使用fastdfs和阿里云的oss实现文件上传以及他们的比较&#xff08;oss根据流量收费&#xff09;。minio的中文文档&#xff1a;https://docs.min.io/cn/ minio安装 首先查询d…

ES6 let 和 const 关键字

一、ES5 的 var 关键字 var 存在变量提升var 允许重复声明&#xff0c;浏览器本身只识别一次&#xff0c;但不会报错var 声明的变量即是全局变量&#xff0c;也相当于给 GO(window) 设置了一个属性而且两者建立映射机制基于 typeof 检测一个没有被声明过的变量&#xff0c;并不…