步驟 2 使用開票協議為使用者建立訂閱(節點示例)

為使用者建立訂閱的第二步是基於現有的啟用計費計劃建立和執行計費協議。此示例假定你已經完成並啟用了上一個示例中的結算方案,並且在該示例中具有該結算方案的 ID 以供參考。

當你設定結算協議以為使用者建立訂閱時,你將遵循 3 個步驟,這可能會讓人想起處理 PayPal 付款:

  1. 你可以建立結算協議,通過 ID 引用基礎結算方案。
  2. 建立後,你將使用者重定向到 PayPal(如果通過 PayPal 付款)以確認訂閱。確認後,PayPal 會使用基礎結算方案中提供的重定向將使用者重定向回你的網站。
  3. 然後,你可以使用通過 PayPal 重定向提供的令牌執行結算協議。

此示例是設定基於 Express 的 HTTP 伺服器以顯示計費協議流程。

要開始這個例子,我們首先需要設定我們的配置。我們新增了四個要求,PayPal SDK,用於處理 JSON 編碼體的 body-parser,用於簡單伺服器整合的 http 和用於 Express 框架的 express。然後,我們定義我們的客戶端 ID 和祕密來建立應用程式,為沙箱配置 SDK,然後配置 bodyParser 來處理 JSON 主體。

var paypal = require('paypal-rest-sdk'),
    bodyParser = require('body-parser'),
    http = require('http'),
    app = require('express')();

var clientId = 'YOUR APPLICATION CLIENT ID';
var secret = 'YOUR APPLICATION SECRET';

paypal.configure({
  'mode': 'sandbox', //sandbox or live
  'client_id': clientId,
  'client_secret': secret
});

app.use(bodyParser.json());

我們在結算協議中的第一步是建立一條路線來處理建立結算協議,並將使用者重定向到 PayPal 以確認該訂閱。我們假設將結算方案 ID 作為查詢字串引數傳遞,例如通過使用上一個示例中的計劃 ID 載入以下 URL:

http://localhost:3000/createagreement?plan=P-3N543779E9831025ECYGDNVQ

我們現在需要使用該資訊來建立結算協議。

app.get('/createagreement', function(req, res){
    var billingPlan = req.query.plan;
    
    var isoDate = new Date();
    isoDate.setSeconds(isoDate.getSeconds() + 4);
    isoDate.toISOString().slice(0, 19) + 'Z';

    var billingAgreementAttributes = {
        "name": "Standard Membership",
        "description": "Food of the World Club Standard Membership",
        "start_date": isoDate,
        "plan": {
            "id": billingPlan
        },
        "payer": {
            "payment_method": "paypal"
        },
        "shipping_address": {
            "line1": "W 34th St",
            "city": "New York",
            "state": "NY",
            "postal_code": "10001",
            "country_code": "US"
        }
    };

    // Use activated billing plan to create agreement
    paypal.billingAgreement.create(billingAgreementAttributes, function (error, billingAgreement){
        if (error) {
            console.error(error);
            throw error;
        } else {
            //capture HATEOAS links
            var links = {};
            billingAgreement.links.forEach(function(linkObj){
                links[linkObj.rel] = {
                    'href': linkObj.href,
                    'method': linkObj.method
                };
            })

            //if redirect url present, redirect user
            if (links.hasOwnProperty('approval_url')){
                res.redirect(links['approval_url'].href);
            } else {
                console.error('no redirect URI present');
            }
        }
    });
});

我們首先從查詢字串中提取開票計劃 ID,然後建立計劃開始時的日期。

下一個物件定義 billingAgreementAttributes 由訂閱的資訊組成。它包含有關計劃的可讀資訊,對計費計劃 ID 的引用,付款方式和運輸詳細資訊(如果訂閱需要)。

接下來,呼叫 billingAgreement.create(...),傳入我們剛剛建立的 billingAgreementAttributes 物件。如果一切都成功,我們應該將一個結算協議物件傳回給我們,其中包含有關我們新建立的訂閱的詳細資訊。該物件還包含許多 HATEOAS 連結,為我們提供了可以對這個新建立的協議採取的後續步驟。我們在這裡關心的那個被標記為 approval_url

我們遍歷所有提供的連結,將它們放入一個容易引用的物件中。如果 approval_url 是其中一個連結,我們會將使用者重定向到該連結,即 PayPal。

此時,使用者確認 PayPal 上的訂閱,並重定向回基礎計費計劃中提供的 URL。除了該 URL,PayPal 還將沿著查詢字串傳遞令牌。該令牌是我們將用於執行(或開始)訂閱的標記。

讓我們在以下路線中設定該功能。

app.get('/processagreement', function(req, res){
    var token = req.query.token;
    
    paypal.billingAgreement.execute(token, {}, function (error, billingAgreement) {
        if (error) {
            console.error(error);
            throw error;
        } else {
            console.log(JSON.stringify(billingAgreement));
            res.send('Billing Agreement Created Successfully');
        }
    });
});

我們從查詢字串中提取令牌,然後呼叫 billingAgreement.execute,傳遞該令牌。如果一切都成功,我們現在擁有該使用者的有效訂閱。返回物件包含有關活動計費協議的資訊。

最後,我們設定 HTTP 伺服器來監聽路由的流量。

//create server
http.createServer(app).listen(3000, function () {
   console.log('Server started: Listening on port 3000');
});