java PayPal支付
牛13转折点 人气:0首先引入 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的同学一点儿参考
加载全部内容