全部
常见问题
产品动态
精选推荐

Java 多商户接入 PayPal(Spring Boot 骨架)

管理 管理 编辑 删除

功能概览

  • 商户入驻(Partner Referrals)
  • 保存并管理 paypal_merchant_id
  • 创建订单(支持指定收款商户 + 平台抽佣)
  • 引导用户跳转 PayPal 支付 + 支付结果处理
  • 订单 Capture(收款)
  • Webhook 验签(支付成功/退款等事件)
  • 多环境(Sandbox / Live)切换

目录结构(建议)

paypal-multitenant/

├─ pom.xml

├─ src/main/java/com/example/paypal/

│  ├─ PayPalApplication.java

│  ├─ config/

│  │  ├─ AppProperties.java

│  │  └─ PayPalConfig.java

│  ├─ core/

│  │  ├─ PayPalApiClient.java

│  │  └─ WebhookVerifier.java

│  ├─ merchant/

│  │  ├─ MerchantEntity.java

│  │  ├─ MerchantRepository.java

│  │  └─ MerchantService.java

│  ├─ order/

│  │  ├─ PayOrderEntity.java

│  │  ├─ PayOrderRepository.java

│  │  ├─ OrderService.java

│  │  └─ dto/

│  │     ├─ CreateOrderRequest.java

│  │     ├─ CreateOrderResponse.java

│  │     └─ CaptureResponse.java

│  ├─ web/

│  │  ├─ OnboardingController.java

│  │  ├─ OrderController.java

│  │  └─ WebhookController.java

│  └─ util/Jsons.java

└─ src/main/resources/

  ├─ application.yml

  └─ logback-spring.xml (可选)

PayPal 客户端 PayPalApiClient.java

package com.example.paypal.core;

import com.example.paypal.config.AppProperties;

import lombok.RequiredArgsConstructor;

import org.apache.hc.client5.http.classic.methods.HttpPost;

import org.apache.hc.client5.http.classic.methods.HttpUriRequestBase;

import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;

import org.apache.hc.client5.http.impl.classic.HttpClients;

import org.apache.hc.core5.http.ContentType;

import org.apache.hc.core5.http.io.entity.StringEntity;

import org.springframework.http.HttpHeaders;

import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;

import java.util.Base64;

@Component

@RequiredArgsConstructor

public class PayPalApiClient {

 private final AppProperties props;


 public String accessToken() throws Exception {

   var url = props.getPaypal().getApiBase() + "/v1/oauth2/token";

   try (CloseableHttpClient client = HttpClients.createDefault()) {

     HttpPost post = new HttpPost(url);

     String basic = Base64.getEncoder().encodeToString((

         props.getPaypal().getClientId() + ":" + props.getPaypal().getClientSecret()

     ).getBytes(StandardCharsets.UTF_8));

     post.addHeader(HttpHeaders.AUTHORIZATION, "Basic " + basic);

     post.addHeader("Accept", "application/json");

     post.addHeader("Accept-Language", "en_US");

     post.setEntity(new StringEntity("grant_type=client_credentials", ContentType.APPLICATION_FORM_URLENCODED));

     return Http.execAndRead(client, post);

   }

 }


 public String post(String path, String jsonBody, String bearer) throws Exception {

   String url = props.getPaypal().getApiBase() + path;

   try (CloseableHttpClient client = HttpClients.createDefault()) {

     HttpPost post = new HttpPost(url);

     decorate(post, bearer);

     post.setEntity(new StringEntity(jsonBody, ContentType.APPLICATION_JSON));

     return Http.execAndRead(client, post);

   }

 }


 private void decorate(HttpUriRequestBase req, String bearer) {

   req.addHeader(HttpHeaders.AUTHORIZATION, "Bearer " + bearer);

   req.addHeader("Content-Type", "application/json");

   if (props.getPaypal().getPartnerAttributionId() != null) {

     req.addHeader("PayPal-Partner-Attribution-Id", props.getPaypal().getPartnerAttributionId());

   }

 }


 // 简化 http 读写

 static class Http {

   static String execAndRead(CloseableHttpClient client, HttpUriRequestBase req) throws Exception {

     return client.execute(req, res -> new String(res.getEntity().getContent().readAllBytes(), StandardCharsets.UTF_8));

   }

 }

}

请登录后查看

小码二开 最后编辑于2025-08-19 09:10:46

快捷回复
回复
回复
回复({{post_count}}) {{!is_user ? '我的回复' :'全部回复'}}
排序 默认正序 回复倒序 点赞倒序

{{item.user_info.nickname ? item.user_info.nickname : item.user_name}} LV.{{ item.user_info.bbs_level || item.bbs_level }}

作者 管理员 企业

{{item.floor}}# 同步到gitee 已同步到gitee {{item.is_suggest == 1? '取消推荐': '推荐'}}
{{item.is_suggest == 1? '取消推荐': '推荐'}}
沙发 板凳 地板 {{item.floor}}#
{{item.user_info.title || '暂无简介'}}
附件

{{itemf.name}}

{{item.created_at}}  {{item.ip_address}}
打赏
已打赏¥{{item.reward_price}}
{{item.like_count}}
{{item.showReply ? '取消回复' : '回复'}}
删除
回复
回复

{{itemc.user_info.nickname}}

{{itemc.user_name}}

回复 {{itemc.comment_user_info.nickname}}

附件

{{itemf.name}}

{{itemc.created_at}}
打赏
已打赏¥{{itemc.reward_price}}
{{itemc.like_count}}
{{itemc.showReply ? '取消回复' : '回复'}}
删除
回复
回复
查看更多
打赏
已打赏¥{{reward_price}}
22
{{like_count}}
{{collect_count}}
添加回复 ({{post_count}})

相关推荐

快速安全登录

使用微信扫码登录
{{item.label}} 加精
{{item.label}} {{item.label}} 板块推荐 常见问题 产品动态 精选推荐 首页头条 首页动态 首页推荐
取 消 确 定
回复
回复
问题:
问题自动获取的帖子内容,不准确时需要手动修改. [获取答案]
答案:
提交
bug 需求 取 消 确 定
打赏金额
当前余额:¥{{rewardUserInfo.reward_price}}
{{item.price}}元
请输入 0.1-{{reward_max_price}} 范围内的数值
打赏成功
¥{{price}}
完成 确认打赏

微信登录/注册

切换手机号登录

{{ bind_phone ? '绑定手机' : '手机登录'}}

{{codeText}}
切换微信登录/注册
暂不绑定
CRMEB客服

CRMEB咨询热线 咨询热线

400-8888-794

微信扫码咨询

CRMEB开源商城下载 源码下载 CRMEB帮助文档 帮助文档
返回顶部 返回顶部
CRMEB客服