java后端PayPal支付实现教程

网友投稿 583 2022-09-08


java后端PayPal支付实现教程

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

com.paypal.sdk

checkout-sdk

1.0.4

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 payPalNotify(@RequestBody PayPalVo payPalVo){

if (ObjectUtils.isEmpty(payPalVo.getOrderNo()) || ObjectUtils.isEmpty(payPalVo.getOutOrderNo()) || ObjectUtils.isEmpty(payPalVo.getOrderType())){

return ResponseModel.error(appConfigStatusCodeService.getStatusCode(payPalVo.getLanguage(), ResponseCnShttp://ate.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.getLahttp://nguage(), 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 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 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 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 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 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 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 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 createOrder(OrderRequest orderRequest) {

OrdersCreateRequest request = new OrdersCreateRequest();

request.header("prefer","return=representation");

request.requestBody(orderRequest);

// PayPalClient payPalClient = new PayPalClient();

HttpResponse 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) {

txQXOpA log.error("第3次调用paypal订单创建失败,失败原因:{}", e2.getMessage());

}

}

}

// String approve = "";

Map 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的同学一点儿参考


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:#yyds干货盘点#List函数index - python基础学习系列(66)
下一篇:Python 运算法重载之右侧加法
相关文章

 发表评论

暂时没有评论,来抢沙发吧~