首先引入 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_MBj0 clientSecret: EMDda7g_Q7KmOiH08qJfg-dAb8d2THkYtzRR #测试的mode mode: sandbox #正式的mode mode: live
/** * @author majun * @email majun6534@dingtalk.com * @date 2021/7/29 * @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支付
/** * 贝宝支付 * * @param payPalVo 请求对象 * @return 返回结果 */ @PostMapping(\"/payPalNotify\") @ApiOperation(value = \"贝宝支付二次验证\") @Deprecated public 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工具类 * * @author majun * @email majun6534@dingtalk.com * @date 2021/7/29 * @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的同学一点儿参考
做猪小侠源码的代理,提供一站式服务
如果你不懂得搭建网站或者服务器,小程序,源码之类的怎么办? 第一通过本站学习各种互联网的技术 第二就是联系客服,我帮帮你搭建(当然要收取部分的费用) 第三成为我们的代理,我们提供整套的服务。