java后端PayPal支付实现教程
首先引入 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的同学一点儿参考
到此这篇关于java后端PayPal支付实现教程的文章就介绍到这了,更多相关java PayPal支付内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!
赞 (0)