SpringBoot实现PayPal订阅支付-JavaScript SDK

目录

PayPal 订阅支付

1、注册PayPal账号

2、Create APP

3、创建订阅计划

4、前端代码实现

5、Java后端代码实现

6、Webhook回调接口

7、官方文档集成资料


PayPal 订阅支付

以下主要实现订阅产品定期支付,前端JavaScript SDK集成方式,后端Java  SpringBoot实现。

官网介绍的流程:

创建一个产品来代表您的商品或服务。
创建一个计划来表示订阅的支付周期。
使用JavaSIRPTSDK显示按钮,启动订阅过程。
买方同意并同意.
按钮调用订阅API来创建订阅。
买方看到订阅确认。

Java对接PayPal国际支付,主要流程如下:

  • 1、注册PayPal账号

  • 1.1  在集成paypal支付接口之前,先自行注册好开发者账号。

        PayPal开发者:https://developer.paypal.com/dashboard/accounts

        sandbox测试账号登录的测试网址:https://www.sandbox.paypal.com

  • 1.2  关于PayPal账号是分环境的,首先区别是Live还是sandbox环境。

  • 1.3再区分开发者账号,商家,客户账号。商家和客户测试账号会在下步创建。

  • 2、Create APP

  2.1  创建一个名称为testApp

  • 2.2 获取到Client ID和Secret key,后面付款完成后,回调数据会使用到。

  • 2.3  创建支付测试账号,点击View details 

进入到:https://developer.paypal.com/dashboard/accounts/

原有两个默认账号也可以使用,这里使用自己新建的账号测试。

  • 3、创建订阅计划

  • 3.1  使用商家账号登录

3.2  注意:上面的链接是直接访问到Live环境的,我们需要使用sandbox环境的登录。

Sandbox环境登录地址:【Log in to your PayPal account

使用3.1图中的账号登录,此处使用Business账号登录,密码可点击查看

账号:sb-ssk1v15353135@business.example.com

   3.3  登录之后,创建订阅计划。

3.3.1选择定期付款

3.3.2 创建计划

3.3.3 创建一个testProductName产品名称

3.3.4 创建一个名称为:company的计划名称 
固定100美元一个月定期收款。

3.3.5 开启计划

3.3.6 获取前端模板代码

复制的模板代码,用于前端创建。

<div id="paypal-button-container-P-4WL110183E9707519M2WPRWQ"></div>
<script src="https://www.paypal.com/sdk/js?client-id=AaplsYta1E3RD3RDLa2UQLtO-jIX9pCRqPvYLtKB7FMcbiCcdHJCNnVSi641WN9DZ5bWTHfJkIvXc6y8&vault=true&intent=subscription" data-sdk-integration-source="button-factory"></script>
<script>
  paypal.Buttons({
      style: {
          shape: 'rect',
          color: 'gold',
          layout: 'vertical',
          label: 'subscribe'
      },
      createSubscription: function(data, actions) {
        return actions.subscription.create({
          /* Creates the subscription */
          plan_id: 'P-4WL110183E9707519M2WPRWQ'
        });
      },
      onApprove: function(data, actions) {
        alert(data.subscriptionID); // You can add optional success message for the subscriber here
      }
  }).render('#paypal-button-container-P-4WL110183E9707519M2WPRWQ'); // Renders the PayPal button
</script>
  • 4、前端代码实现

4.1、编写前端测试demo

详细的参数配置,可参考官方文档。

JavaScript SDK reference

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>PayPal Integration</title>
<script src="https://www.paypal.com/sdk/js?client-id=AaplsYta1E3RD3RDLa2UQLtO-jIX9pCRqPvYLtKB7FMcbiCcdHJCNnVSi641WN9DZ5bWTHfJkIvXc6y8&vault=true&intent=subscription" 
data-sdk-integration-source="button-factory"></script>

</head>
<body>
<div id="paypal-button-container-P-4WL110183E9707519M2WPRWQ"></div>
<script>
  paypal.Buttons({
      style: {
          shape: 'rect',
          color: 'gold',
          layout: 'vertical',
          label: 'subscribe'
      },
      createSubscription: function(data, actions) {
        return actions.subscription.create({
          /* Creates the subscription */
          plan_id: 'P-4WL110183E9707519M2WPRWQ'
        });
      },
      onApprove: function(data, actions) {
        alert(data.subscriptionID); // You can add optional success message for the subscriber here
      }
  }).render('#paypal-button-container-P-4WL110183E9707519M2WPRWQ'); // Renders the PayPal button

</script>
</body>
</html>

4.2、运行效果

可直接测试支付

此处需要使用3.1步骤中Personal账号支付。

4.3、测试支付

使用账号:sb-x38yy31910915@personal.example.com

密码可点击复制使用

之前创建的订阅产品

付款完成,前端弹出订阅Id,后续我们也可以在付款之后跳转页面,处理付款成功之后的逻辑。

4.4查看付款后,收到的金额。登录商家账号查看。

收款总额$100

  • 5、Java后端代码实现

5.1 引入相关SDK

这里使用的是IJpay ,导入IJpay的依赖。

        <!-- 支付相关 -->
        <dependency>
            <groupId>com.github.javen205</groupId>
            <artifactId>IJPay-PayPal</artifactId>
            <version>${pay.version}</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.paypal.sdk/rest-api-sdk -->
        <dependency>
            <groupId>com.paypal.sdk</groupId>
            <artifactId>rest-api-sdk</artifactId>
            <version>1.14.0</version>
        </dependency>

5.2 添加PayPal 配置。

为了数据验证和关联自己新建的APP。

 添加yml 配置文件

pay:
  paypal: 
    clientId: AaplsYta1E3RD3RDLa2UQLtO-jIX9pCRqPvYLtKB7FMcbiCcdHJCNnVSi641WN9DZ5bWTHfJkIvXc6y8
    secret: xxxxxx
    sandBox: true
    webhookId: 6SF47866RX680211K

这里需要获取Client ID、Secret key 和Webhook ID。这些直接在App name里面获取。

获取Webhook ID

读取配置的代码


import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * <p>IJPay 让支付触手可及,封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。</p>
 *
 * <p>不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。 </p>
 *
 *
 * @author Javen
 */
@Component
@ConfigurationProperties(prefix = "pay.paypal")
public class PayPalBean {
    private String clientId;
    private String secret;
    private Boolean sandBox;
    private String domain;

    private String webhookId;

    public String getClientId() {
        return clientId;
    }

    public void setClientId(String clientId) {
        this.clientId = clientId;
    }

    public String getSecret() {
        return secret;
    }

    public void setSecret(String secret) {
        this.secret = secret;
    }

    public Boolean getSandBox() {
        return sandBox;
    }

    public void setSandBox(Boolean sandBox) {
        this.sandBox = sandBox;
    }

    public String getDomain() {
        return domain;
    }

    public void setDomain(String domain) {
        this.domain = domain;
    }

    public String getWebhookId() {
        return webhookId;
    }

    public void setWebhookId(String webhookId) {
        this.webhookId = webhookId;
    }

    @Override
    public String toString() {
        return "PayPalBean{" +
                "clientId='" + clientId + '\'' +
                ", secret='" + secret + '\'' +
                ", sandBox=" + sandBox +
                ", domain='" + domain + '\'' +
                '}';
    }
}

5.3 回调接口实现

    /**
     * PayPal 订阅回调
     *
     * @param req
     * @param resp
     */
    @PostMapping("/callback")
    public void callback(HttpServletRequest req, HttpServletResponse resp) {
        try {
            // ### Api Context
            APIContext apiContext = new APIContext(payPalBean.getClientId(), payPalBean.getSecret(),
                    payPalBean.getSandBox() ? "sandbox" : "live");
            // Set the webhookId that you received when you created this webhook.
            apiContext.addConfiguration(Constants.PAYPAL_WEBHOOK_ID, payPalBean.getWebhookId());

            //读取回调的数据
            String body = req.getReader().lines().collect(Collectors.joining(System.lineSeparator()));
            Boolean result = Event.validateReceivedEvent(apiContext, getHeadersInfo(req), body);
            //验签
            if(result){
                JSONObject entries = new JSONObject(body);
                String eventType = entries.getStr("event_type");
                JSONObject resource = entries.getJSONObject("resource");
                String state = resource.getStr("state");
                // 支付成功
                if ("PAYMENT.SALE.COMPLETED".equals(eventType)) {
                    if (state.equals("completed")) {
                        String subscriptionId = resource.getStr("billing_agreement_id");
                        //TODO 根据订阅处理相关逻辑
                    }
                } else if ("BILLING.SUBSCRIPTION.CANCELLED".equals(eventType)) {
                    // 订阅已取消
                } else {
                    log.info("待处理回调body:{}", body);
                }
            }else{
                //验签失败
            }
            //需要返回200,不然PayPal会多次回调
            resp.setStatus(HttpServletResponse.SC_OK);
        } catch (Exception e) {
            log.error("callback回调错误:{}", ExceptionUtils.getStackTrace(e));
            resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        }
    }

  • 6、Webhook回调接口

6.1 上面是实现了收款功能,但是完成收款后,需要给客户授权,或者给相应的购买后的权限还没有实现,这里就需要实现付款完成监听事件回调。

6.2 创建webhook Events 回调地址

进入到 Apps & Credentials 创建的APP下,添加Add Webhook 。

官方介绍Webhook:

Configure webhooks to notify your app when certain events occur. To configure a webhook, define your webhook listener URL and a list of events for which to listen. You can configure up to ten webhooks. Each webhook can subscribe to either specific events or all events. To learn more about webhooks, see webhooks notifications.

填写回调接口,用于接受PayPal回调,处理付款,取消订阅等业务。

如果用于本地测试,这里可以填写映射到外网的域名地址或者IP地址。

我这里使用的是cpolar映射工具。回调到我项目中的callback方法,即步骤5.3中的方法。

选择要监听的事件,这里选择支付成功:PAYMENT.SALE.COMPLETED

和订阅取消:BILLING.SUBSCRIPTION.CANCELLED。

可以根据自己业务需求选择,处理对应的事件。

6.3 以上,所有配置都已完成,可以再次付款测试回调数据。

付款完成之后,可以看到后端接口回调数据。

并且也通过了validateReceivedEvent数据验签,这时候就可以根据回调数据处理后面的业务了。

回调数据如下:

可以看到有订阅ID、订单总额和订单完成状态等。

{
    "id": "WH-1N771973Y65413823-5JY73712GC073741L",
    "event_version": "1.0",
    "create_time": "2024-08-04T00:33:24.707Z",
    "resource_type": "sale",
    "event_type": "PAYMENT.SALE.COMPLETED",
    "summary": "Payment completed for $ 100.0 USD",
    "resource": {
        "billing_agreement_id": "I-NU99SS3VP94W",
        "amount": {
            "total": "100.00",
            "currency": "USD",
            "details": {
                "subtotal": "100.00"
            }
        },
        "payment_mode": "INSTANT_TRANSFER",
        "update_time": "2024-08-04T00:33:20Z",
        "create_time": "2024-08-04T00:33:20Z",
        "protection_eligibility_type": "ITEM_NOT_RECEIVED_ELIGIBLE,UNAUTHORIZED_PAYMENT_ELIGIBLE",
        "transaction_fee": {
            "currency": "USD",
            "value": "3.70"
        },
        "protection_eligibility": "ELIGIBLE",
        "links": [{
                "method": "GET",
                "rel": "self",
                "href": "https://api.sandbox.paypal.com/v1/payments/sale/78002905YC102620N"
            }, {
                "method": "POST",
                "rel": "refund",
                "href": "https://api.sandbox.paypal.com/v1/payments/sale/78002905YC102620N/refund"
            }
        ],
        "id": "78002905YC102620N",
        "state": "completed",
        "invoice_number": ""
    },
    "links": [{
            "href": "https://api.sandbox.paypal.com/v1/notifications/webhooks-events/WH-1N771973Y65413823-5JY73712GC073741L",
            "rel": "self",
            "method": "GET"
        }, {
            "href": "https://api.sandbox.paypal.com/v1/notifications/webhooks-events/WH-1N771973Y65413823-5JY73712GC073741L/resend",
            "rel": "resend",
            "method": "POST"
        }
    ]
}

也可以从PayPal后台回调事件中查看,点击Event ID可查看回调的数据。

至此,PayPal订阅支付已经完成。

关于PayPal支付开发,个人认为首先还是得多读PayPal提供的开发文档,熟悉整个流程以及详细的参数配置,关于一些界面的配置和回调的参数都可以从文档中查询到。

  • 7、官方文档集成资料

Subscriptions

JavaScript SDK 集成资料,以及相关参数配置说明。

https://developer.paypal.com/sdk/js/reference/

PayPal还有Checkout支付,API集成方式等,都可以从PayPal文档获取资料。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值