如何在同一页面上显示 PayPal Smart Subscription Button 和 PayPal Smart Capture Button?

How can I show a PayPal Smart Subscription Button and a PayPal Smart Capture Button on the same page?

尝试在同一页面添加 PayPal 订阅按钮和一次性付款的 capture/order 按钮时,您需要使用不同的参数导入 PayPal 的 Javascript 文件两次(intent=subscription&vault=true 而不是 intent=capture)

如果您尝试导入这两个按钮将不会呈现。

如何在同一页面上同时显示 PayPal 订阅和 PayPal 一次性付款智能按钮?

重现问题的示例代码:

<script src="https://www.paypal.com/sdk/js?client-id={{YOUR CLIENT ID}}&currency=USD"></script>
<script src="https://www.paypal.com/sdk/js?client-id={{YOUR CLIENT ID}}&currency=USD&intent=subscription&vault=true"></script>

<div id="some-container"></div>
<div id="some-subscription-container"></div>

<script>
    paypal.Buttons().render('#some-container');
    paypal.Buttons().render('#some-subscription-container');
</script>

经过几个小时的斗争,我找到了一个非常有效的解决方案,可以在同一页面上显示两个按钮(甚至每个按钮中的许多按钮),并且想分享它,这样我就可以减轻其他人的痛苦。

1 - 两次导入库

第一个问题是如何使用不同的参数同时导入两个 PayPal Javascript 文件。解决方案是在脚本标签上使用 data-namespace,如下所示:

<script src="https://www.paypal.com/sdk/js?client-id={{YOUR CLIENT ID}}&currency=USD" data-namespace="paypal_one_time"></script>
<script src="https://www.paypal.com/sdk/js?client-id={{YOUR CLIENT ID}}&currency=USD&intent=subscription&vault=true" data-namespace="paypal_subscriptions"></script>

2 - 显示两个按钮(或更多)

现在要呈现您需要使用这些名称空间而不是 paypal 变量的按钮。例如:

paypal_one_time.Buttons().render('#some-container');
paypal_subscriptions.Buttons().render('#some-subscription-container');

3 - 一次性支付流程后订阅中断

您会发现的最后一个问题是单击 one_time 付款按钮会破坏订阅按钮。如果您尝试在一次性按钮之后点击订阅,它将不起作用(说您没有足够的权限并关闭弹出窗口window)。

要解决此问题,最简单的方法是在每次一次性付款流程完成时重新呈现页面上的订阅按钮(在 Buttons() 选项内的 onApproved/onCancelled/onError 方法中) -时间支付按钮)。

onApprove: function(data, actions) {
    return actions.order.capture().then(function(orderData) {
             // process your one time payment

             // re-render subscription buttons because now they are broken!
             reRenderSubscriptionButtons();
    });
},
onCancel: function(data) {
             reRenderSubscriptionButtons();
},

对于 one_time_button 中的那些事件,只需调用一个函数来执行如下操作:

function reRenderSubscriptionButtons() {
   // remove everything from the container
   document.getElementById("some-subscription-container").innerHTML='';

   // render the subscription buttons again (you can call the same function you use to render it the first time too)
   paypal_subscriptions.Buttons().render('#some-subscription-container');
}