PayPal.java 7.0 KB
package com.aigeo.util.pay;

import com.aigeo.entity.*;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Date;
import java.util.Objects;
import java.util.UUID;

@Slf4j
@Component
public class PayPal implements PaymentStrategy{

    private static final String TOKEN_URL = "/v1/oauth2/token";

    private static final String ORDER_URL = "/v2/checkout/orders";

//    @Autowired
//    private PaypalOrderRecordDao paypalOrderRecordDao;

    @Override
    public String pay(PayDto payDto) throws IOException {
        ApiConfig config = payDto.getApiConfig();
        String tokenUrl=config.getApiUrl()+TOKEN_URL;
        String token = getAccessToken(tokenUrl,config.getApiId(),config.getApiKey());
        OkHttpClient client = new OkHttpClient();
        String url=config.getApiUrl()+ORDER_URL;

        PayPalDTO palDTO = new PayPalDTO();
        palDTO.setIntent("CAPTURE");
        PayPalDTO.PaymentSource paymentSource = new PayPalDTO.PaymentSource();
        PayPalDTO.PaymentSource.Paypal paypal = new PayPalDTO.PaymentSource.Paypal();

        PayPalDTO.PaymentSource.Paypal.ExperienceContext experienceContext = new PayPalDTO.PaymentSource.Paypal.ExperienceContext();
        experienceContext.setReturn_url(config.getApiRedirectUri()+"/"+payDto.getCompanyId());
        experienceContext.setCancel_url(config.getApiRedirectUri());

        paypal.setExperience_context(experienceContext);
        paymentSource.setPaypal(paypal);
        palDTO.setPayment_source(paymentSource);

        PayPalDTO.PurchaseUnit.Amount amount = new PayPalDTO.PurchaseUnit.Amount();
        amount.setCurrency_code("USD");
        amount.setValue(payDto.getAmount());

        PayPalDTO.PurchaseUnit purchaseUnit = new PayPalDTO.PurchaseUnit();
        purchaseUnit.setCustom_id(payDto.getOrderId());
        purchaseUnit.setAmount(amount);
        PayPalDTO.PurchaseUnit[] list = new PayPalDTO.PurchaseUnit[]{purchaseUnit};
        palDTO.setPurchase_units(list);

        String toJson = JSONObject.toJSONString(palDTO);
        RequestBody body = RequestBody.create(toJson, MediaType.parse("application/json; charset=utf-8"));
        String string = UUID.randomUUID().toString();
        Request request = new Request.Builder()
                .url(url)
                .post(body)
                .addHeader("Content-Type", "application/json")
                .addHeader("PayPal-Request-Id", string)
                .addHeader("Authorization", "Bearer "+token)
                .build();

        try (Response response = client.newCall(request).execute()) {
            if (response.isSuccessful() && response.body() != null) {
                String res = Objects.requireNonNull(response.body()).string();
                log.info("响应内容:{}",res);
                PayPalResponse payPalResponse = JSONObject.parseObject(res, PayPalResponse.class);
                PayPalResponse.ResMsg[] link = payPalResponse.getLinks();
                log.info("订单:{}支付地址:{}",payDto.getOrderId(),link[1].getHref());
                Date now = new Date();
                SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
                String formattedTime = formatter.format(now);
                PayPalOrderRecord orderRecord = new PayPalOrderRecord();
                orderRecord.setCompanyId(payDto.getCompanyId());
                orderRecord.setOrderId(payDto.getOrderId());
                orderRecord.setPaypalId(payPalResponse.getId());
                orderRecord.setState(0);
                orderRecord.setCreateTime(formattedTime);
                orderRecord.setUpdateTime(formattedTime);
//                paypalOrderRecordDao.addPojo(orderRecord);
                return link[1].getHref();
            } else {
                System.out.println("Request failed: " + response.code());
                System.out.println("Response: " + response.body().string());
                return null;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public void closeTrade(String orderId, String mchId, ApiConfig apiConfig) {

    }

    @Override
    public void refund() {

    }

    public static String getAccessToken(String tokenUrl,String clientId,String clientSecret) throws IOException {
        OkHttpClient client = new OkHttpClient();

        // 创建请求体
        RequestBody body = new FormBody.Builder()
                .add("grant_type", "client_credentials")
                .build();

        // 创建请求
        Request request = new Request.Builder()
                .url(tokenUrl)
                .post(body)
                .addHeader("Content-Type", "application/x-www-form-urlencoded")
                .addHeader("Authorization", "Basic " + getBasicAuth(clientId,clientSecret))
                .build();

        // 发送请求
        try (Response response = client.newCall(request).execute()) {
            if (response.isSuccessful() && response.body() != null) {
                // 解析响应
                String responseBody = response.body().string();
                System.out.println("*-*--**--*-*-*-*-**--**-*-"+parseAccessToken(responseBody));
                return parseAccessToken(responseBody);
            } else {
                throw new IOException("Failed to get access token: " + response.code());
            }
        }
    }

    private static String getBasicAuth(String clientId,String clientSecret) {
        return Base64.getEncoder().encodeToString((clientId + ":" + clientSecret).getBytes());
    }

    private static String parseAccessToken(String responseBody) {
        // 简单解析 JSON 响应
        String[] parts = responseBody.split(",");
        for (String part : parts) {
            if (part.contains("access_token")) {
                return part.split(":")[1].trim().replace("\"", "");
            }
        }
        throw new IllegalArgumentException("Access token not found in response: " + responseBody);
    }

    public static String extractPayerActionUrl(String jsonResponse) {
        // 将 JSON 字符串解析为 JSONObject
        JSONObject jsonObject = JSON.parseObject(jsonResponse);

        // 获取 links 数组
        JSONArray links = jsonObject.getJSONArray("links");

        // 遍历 links 数组
        for (int i = 0; i < links.size(); i++) {
            JSONObject link = links.getJSONObject(i);
            // 检查 rel 是否为 payer-action
            if ("payer-action".equals(link.getString("rel"))) {
                // 返回 href 值
                return link.getString("href");
            }
        }

        // 如果没有找到 payer-action 链接,返回 null
        return null;
    }

    @Override
    public String getChannel() {
        return "paypal";
    }
}