{"id":2128,"date":"2016-10-31T03:00:00","date_gmt":"2016-10-31T03:00:00","guid":{"rendered":"https:\/\/www.microsoft.com\/reallifecode\/index.php\/2016\/10\/31\/integrating-payments-with-bots\/"},"modified":"2020-03-15T06:54:41","modified_gmt":"2020-03-15T13:54:41","slug":"integrating-payments-with-bots","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/ise\/integrating-payments-with-bots\/","title":{"rendered":"Integrating Payments with Bots"},"content":{"rendered":"<h1 id=\"background\">Background<\/h2>\n<p>At a recent collaboration with a customer, we learned about a few integrations they had wanted to build for Bots running with the Microsoft Bot Framework. One such integration was with a payments service provider, like PayPal. We had created an example of this integration with the C# SDK for Bot Framework, but no such example existed for the Node SDK. As such, I\u2019d like to demonstrate how straightforward it is to build a PayPal integration for bots made using Bot Framework\u2019s Node SDK.<\/p>\n<h2 id=\"set-up-an-application\">Set up an application<\/h2>\n<p>You will need to register the bot application with PayPal to generate the requisite keys to access the Paypal APIs. After logging into PayPal, <a href=\"https:\/\/developer.paypal.com\/developer\/applications\/create\">go to the developer center page to create an application<\/a>. Copy the <strong>Client ID<\/strong> and the <strong>Client Secret<\/strong> (the <strong>Client Secret<\/strong> will be hidden from you until you select \u2018Show\u2019 with your cursor).<\/p>\n<p>We additionally need to <a href=\"https:\/\/developer.paypal.com\/developer\/accounts\/create\">create a test user<\/a> to use with the PayPal sandbox. When testing in the <strong>sandbox<\/strong> environment, you can use this test account, which doesn\u2019t require adding a credit card or funding the account.<\/p>\n<h2 id=\"setup-node-and-grab-the-sample\">Setup Node and grab the sample<\/h2>\n<p>The following steps assume you have Node.js, npm, and a Bot Framework Emulator installed on your computer. To install Node and npm, visit <a href=\"https:\/\/nodejs.org\/en\/download\/\">the Node download page<\/a> and select \u2018Current.\u2019 At the time of writing, the current iteration of Node is version 6.7.0, but any version that is 4.x or above should work. We do not recommend lower versions as the semantics of some keywords have changed between versions.<\/p>\n<p>The cross platform Bot Framework Emulator is <a href=\"https:\/\/docs.botframework.com\/en-us\/tools\/bot-framework-emulator\/\">available to download here<\/a>.<\/p>\n<p>From here on, we\u2019ll reference and discuss the code available <a href=\"https:\/\/github.com\/bnookala\/node-paymentbot\">on Github<\/a>. Using <code class=\"highlighter-rouge\">git<\/code>, clone the repository onto your computer in your terminal of choice: <code class=\"highlighter-rouge\">git clone https:\/\/github.com\/bnookala\/node-paymentbot<\/code>, <code class=\"highlighter-rouge\">cd<\/code> into this directory and run <code class=\"highlighter-rouge\">npm install<\/code> to download the module dependencies.<\/p>\n<h2 id=\"running-the-sample\">Running the sample<\/h2>\n<ol>\n<li><code class=\"highlighter-rouge\">cd<\/code> into the <code class=\"highlighter-rouge\">node-paymentbot<\/code> directory<\/li>\n<li><code class=\"highlighter-rouge\">npm install<\/code> to install the module dependencies<\/li>\n<li>Set the <code class=\"highlighter-rouge\">PAYPAL_CLIENT_ID<\/code>, <code class=\"highlighter-rouge\">PAYPAL_CLIENT_SECRET<\/code>, and <code class=\"highlighter-rouge\">PAYPAL_CLIENT_MODE<\/code> environment variables in your terminal to the copied <strong>Client ID<\/strong> from PayPal, the copied <strong>Client Secret<\/strong> from PayPal, and <strong>\u201csandbox\u201d<\/strong> respectively. You can optionally set the <code class=\"highlighter-rouge\">PORT<\/code> environment variable to customize which port the application is bound to, but it will default to 3978.<\/li>\n<li>run <code class=\"highlighter-rouge\">node app.js<\/code>, note the URL that it writes the console, i.e., <code class=\"highlighter-rouge\">restify listening to http:\/\/[::]:3978<\/code><\/li>\n<li>To configure the Bot Framework Emulator, start the emulator application, and enter the bot messaging endpoint. For a locally running bot it should be: <code class=\"highlighter-rouge\">http:\/\/localhost:3978\/api\/messages<\/code><\/li>\n<li>Start interacting with the bot!<\/li>\n<\/ol>\n<h1 id=\"building-a-payment-flow-from-scratch\">Building a payment flow from scratch<\/h2>\n<p>PayPal offers many APIs and products for creating and executing payments between users and businesses. To keep our integration straightforward, we\u2019ll focus on one relatively simple flow, which involves user approval of payment before we\u2019re able to execute and receive a payment. The full flow is described <a href=\"https:\/\/developer.paypal.com\/docs\/integration\/web\/accept-paypal-payment\/\">in PayPal\u2019s documentation<\/a> in detail, but we\u2019ll be using <a href=\"https:\/\/github.com\/paypal\/PayPal-node-SDK\">PayPal\u2019s Node SDK<\/a> to remove some of the boilerplate in creating and executing the payments.<\/p>\n<h2 id=\"integrating-paypal-into-a-bot\">Integrating PayPal into a Bot<\/h2>\n<p>To use the PayPal Node SDK, we must require it as a module, and configure it with the <strong>Client ID<\/strong> and <strong>Client Secret<\/strong> variables we generated from the PayPal dashboard earlier. PayPal also provides a sandbox environment for testing transactions. We\u2019ll use this environment here to test payments. In practice, when deploying to a production service, you\u2019ll likely want to use different credentials. One popular way to achieve this bucketed approach to deployment is through the underlying system\u2019s environment variables. This way, your code can be environment-agnostic, and you won\u2019t need to keep your <strong>Client ID<\/strong> and <strong>Client Secret<\/strong> variables in your code. When configured, the <code class=\"highlighter-rouge\">paypal<\/code> module will be able to create and execute payments and transactions:<\/p>\n<pre><code>\r\nFile: paypal_ex.js\r\n------------------\r\n\r\nconst paypal = require(&#039;paypal-rest-sdk&#039;);\r\n\r\npaypal.configure({\r\n    &#039;mode&#039;: process.env.PAYPAL_CLIENT_MODE,\r\n    &#039;client_id&#039;: process.env.PAYPAL_CLIENT_ID,\r\n    &#039;client_secret&#039;: process.env.PAYPAL_CLIENT_SECRET\r\n});\r\n<\/code><\/pre>\n<p>To set up our bot, we\u2019ll need to create an instance of a <code class=\"highlighter-rouge\">ChatConnector<\/code> and an instance of a <code class=\"highlighter-rouge\">UniversalBot<\/code>. We\u2019ll also need to create an HTTP server, for the <code class=\"highlighter-rouge\">ChatConnector<\/code> instance to listen on. A <code class=\"highlighter-rouge\">ChatConnector<\/code> allows our Bot to listen and respond on multiple types of messaging channels. Bot Framework currently supports numerous <a href=\"https:\/\/docs.botframework.com\/en-us\/faq\/#what-channels-does-the-bot-framework-currently-support\">popular messaging channels<\/a>, and is consistently adding more. We\u2019ll use the <code class=\"highlighter-rouge\">UniversalBot<\/code> instance to define our bot\u2019s logic (i.e. how it should respond and react when a user performs an action):<\/p>\n<pre><code>\r\nFile: bot_ex.js\r\n---------------\r\n\r\nconst restify = require(&#039;restify&#039;);\r\nconst builder = require(&#039;botbuilder&#039;);\r\n\r\n\/\/ A connector connects a bot on bot framework to various messaging services that a bot\r\n\/\/ can talk to.\r\nlet connector = new builder.ChatConnector({\r\n    appId: undefined,\r\n    appPassword: undefined\r\n});\r\n\r\n\/\/ A bot listens and reacts to messages that the connector picks up on.\r\nlet bot = new builder.UniversalBot(connector);\r\n\r\n\/\/ We&#039;re using restify here to set up an HTTP server, and then adding the queryParser middleware,\r\n\/\/ which will parse the query string into on object on any requests.\r\nlet server = restify.createServer();\r\nserver.use(restify.queryParser());\r\n\r\n\/\/ The server will start listening on this port defined in the environment.\r\nserver.listen(process.env.PORT, function () {\r\n   console.log(&#039;%s listening to %s&#039;, server.name, server.url);\r\n});\r\n\r\n\/\/ Messages are posted to this endpoint. We ask the connector to listen at this endpoint for new messages.\r\nserver.post(&#039;\/api\/messages&#039;, connector.listen());\r\n<\/code><\/pre>\n<p>This setup is great, but our bot doesn\u2019t do anything yet; we haven\u2019t defined any logic for it. Let\u2019s step back and define a use case for this bot: a city government charges a resident for their parking fine and the resident logs on to complete that payment. This example is straightforward enough that we can build it using a single dialog combined with a waterfalled conversation. For more background on dialogs and conversation, please <a href=\"https:\/\/docs.botframework.com\/en-us\/node\/builder\/guides\/core-concepts\/#collecting-input\">read the related section of the Bot Framework documentation<\/a>. A stubbed out example is as follows:<\/p>\n<pre><code>\r\nFile: bot_dialog_stubbing.js\r\n----------------------------\r\n\r\n\/\/ The root dialog of our bot simply just jumps straight into the\r\n\/\/ business logic of paying a fine.\r\nbot.dialog(&#039;\/&#039;, function (session, args) {\r\n        session.beginDialog(&#039;listFines&#039;);\r\n});\r\n\r\n\/\/ Simple three step dialog to list &#039;fines&#039; that a user has received, and allow\r\n\/\/ a user to &#039;pay&#039; them.\r\nbot.dialog(&#039;listFines&#039;, [\r\n    function (session, args) {\r\n        console.log(&#039;List Fines Dialog&#039;);\r\n        session.send(&#039;You have 1 outstanding fine:&#039;);\r\n\r\n        session.send(&#039;Parking Fine Violation&#039;);\r\n        builder.Prompts.choice(session, &quot;What would you like to do?&quot;, [&quot;Pay fine&quot;, &quot;Cancel&quot;]);\r\n    },\r\n    function (session, results, next) {\r\n        let choice = results.response;\r\n\r\n        if (choice.entity === &#039;Cancel&#039;) {\r\n            return;\r\n        }\r\n\r\n        \/\/ TODO: Create a payment, and ask the user to act on it.\r\n    },\r\n    function (session, results) {\r\n        session.send(&#039;Thanks for your payment!&#039;)\r\n    },\r\n]);\r\n<\/code><\/pre>\n<p>Now, our bot will be able to respond to conversation. Let\u2019s test it in the bot framework emulator:<\/p>\n<p> <img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/cse\/wp-content\/uploads\/sites\/55\/2016\/10\/emulator.png\" alt=\"Image emulator\" width=\"1010\" height=\"761\" class=\"aligncenter size-full wp-image-11094\" srcset=\"https:\/\/devblogs.microsoft.com\/ise\/wp-content\/uploads\/sites\/55\/2016\/10\/emulator.png 1010w, https:\/\/devblogs.microsoft.com\/ise\/wp-content\/uploads\/sites\/55\/2016\/10\/emulator-300x226.png 300w, https:\/\/devblogs.microsoft.com\/ise\/wp-content\/uploads\/sites\/55\/2016\/10\/emulator-768x579.png 768w\" sizes=\"(max-width: 1010px) 100vw, 1010px\" \/><\/p>\n<p>Our bot can now recognize that we want to pay our fine, but it does not yet know how to process that fine. <a href=\"https:\/\/gist.github.com\/bnookala\/a8c8c352e4c6180e822655fa311aa204#file-bot_dialog_stubbing-js-L24\">Line 24<\/a> of the above gist describes a \u201cTODO\u201d: creating a payment and asking the user to approve it. This point is the first step in our two-step approval\/execution flow for collecting payment from a user. Let\u2019s create a function, <code class=\"highlighter-rouge\">createAndSendPayment<\/code>, that can create the payment using the PayPal Node SDK, and provide a link that the user can go to the approve the payment. We\u2019ll use the function <code class=\"highlighter-rouge\">paypal.payment.create<\/code> that the Paypal Node SDK offers to create this payment. The first argument to this function is a JSON object, and the second is a callback that is executed upon success or failure. The schema of the JSON object defines the payment that the user will approve, and includes the name, description, amount, and URLs that PayPal will redirect to on approval or cancellation. The full schema of the JSON object that PayPal requires for payment creation is <a href=\"https:\/\/developer.paypal.com\/docs\/api\/payments\/#payment_create_request\">described in their documentation<\/a>. The code as follows describes a function that builds our payment JSON, and one that takes this built JSON, creates a payment and asks the user to approve it:<\/p>\n<pre><code>\r\nFile: payment_json_ex.js\r\n------------------------\r\n\r\n\r\n\/**\r\n * This function creates and returns an object that is passed through to the PayPal Node SDK\r\n * to create a payment that a user must manually approve.\r\n *\r\n * See https:\/\/developer.paypal.com\/docs\/api\/payments\/#payment_create_request for a description of the fields.\r\n *\/\r\nfunction createPaymentJson (returnUrl, cancelUrl) {\r\n    return {\r\n        &quot;intent&quot;: &quot;sale&quot;,\r\n        &quot;payer&quot;: {\r\n            &quot;payment_method&quot;: &quot;paypal&quot;\r\n        },\r\n        &quot;redirect_urls&quot;: {\r\n            &quot;return_url&quot;: returnUrl,\r\n            &quot;cancel_url&quot;: cancelUrl\r\n        },\r\n        &quot;transactions&quot;: [{\r\n            &quot;item_list&quot;: {\r\n                &quot;items&quot;: [{\r\n                    &quot;name&quot;: &quot;Fine&quot;,\r\n                    &quot;sku&quot;: &quot;ParkingFine&quot;,\r\n                    &quot;price&quot;: &quot;1.00&quot;,\r\n                    &quot;currency&quot;: &quot;USD&quot;,\r\n                    &quot;quantity&quot;: 1\r\n                }]\r\n            },\r\n            &quot;amount&quot;: {\r\n                &quot;currency&quot;: &quot;USD&quot;,\r\n                &quot;total&quot;: &quot;1.00&quot;\r\n            },\r\n            &quot;description&quot;: &quot;This is your fine. Please pay it :3&quot;\r\n        }]\r\n    };\r\n}\r\n\/**\r\n * Creates a payment on paypal that a user must approve.\r\n *\/\r\nfunction createAndSendPayment (session) {\r\n    console.log(&#039;Creating Payment&#039;);\r\n\r\n    let paymentJson = createPaymentJson(&#039;http:\/\/localhost&#039;, &#039;http:\/\/localhost&#039;);\r\n\r\n    paypal.payment.create(paymentJson, function (error, payment) {\r\n        if (error) {\r\n            throw error;\r\n        } else {\r\n            \/\/ The SDK returns a payment object when the payment is successfully created.\r\n            \/\/ This object has a few properties, described at length here:\r\n            \/\/ https:\/\/developer.paypal.com\/docs\/api\/payments\/#payment_create_response\r\n            \/\/ We&#039;re looking for the &#039;approval_url&#039; property, which the user must go to\r\n            \/\/ to approve the transaction before we can actively execute the transaction.\r\n            for (var index = 0; index &lt; payment.links.length; index++) {\r\n                if (payment.links[index].rel === &#039;approval_url&#039;) {\r\n                    session.send(&quot;Please pay your fine: &quot; + payment.links[index].href);\r\n                }\r\n            }\r\n        }\r\n    });\r\n};\r\n<\/code><\/pre>\n<p>The callback (<a href=\"https:\/\/gist.github.com\/bnookala\/a8c8c352e4c6180e822655fa311aa204#file-payment_json_ex-js-L44-L59\">starting at Line 44<\/a>) passed as the second parameter looks through the <code class=\"highlighter-rouge\">payment<\/code> object received as an argument and searches for an <code class=\"highlighter-rouge\">approval_url<\/code> property, which can be presented to the user. The user must visit this URL and approve the payment before we can continue and execute the payment. We use a Bot Framework built-in, <code class=\"highlighter-rouge\">builder.Prompts.text<\/code>, to display the approval URL to the user.<\/p>\n<p>With the user having visited the URL and approved a payment, we must now execute the payment. To do that, we must create a <code class=\"highlighter-rouge\">redirect_url<\/code> and provide that in the JSON object for payment creation. PayPal will then redirect our user to this endpoint, which will be hosted by us on the HTTP server we had set up earlier. Soon, we\u2019ll use this endpoint to perform the payment execution. Our code now has a endpoint (<a href=\"https:\/\/gist.github.com\/bnookala\/a8c8c352e4c6180e822655fa311aa204#file-redirect_ex-js-L3-L6\">lines 3 through 6<\/a>) that PayPal will redirect to:<\/p>\n<pre><code>\r\nFile: redirect_ex.js\r\n--------------------\r\n\r\n\/\/ This endpoint describes the approval redirect endpoint that you can provide in the JSON blob passed to PayPal.\r\n\/\/ When a user approves a payment, PayPal will redirect the user to this.\r\nserver.get(&#039;approvalComplete&#039;, function (req, res, next) {\r\n    console.log(&#039;User approved payment!&#039;);\r\n    res.send(200);\r\n});\r\n\r\nfunction createReturnUrl () {\r\n    let url = require(&#039;url&#039;);\r\n    \/\/ This object encodes the endpoint that PayPal redirects to when.\r\n    \/\/ a user approves the payment\r\n    let urlObject = {\r\n        protocol: &#039;http&#039;,\r\n        hostname: &#039;localhost&#039;,\r\n        port: configuration.PORT,\r\n        pathname: &#039;approvalComplete&#039;,\r\n    }\r\n\r\n    return url.format(urlObject);\r\n};\r\n\r\nfunction createAndSendPayment (session) {\r\n  let returnUrl = createReturnUrl();\r\n  let paymentJson = createPaymentJson(returnUrl);\r\n\r\n  \/\/ create payment, etc\u00e2\u20ac\u00a6\r\n};\r\n<\/code><\/pre>\n<p>To execute an approved payment, we use the <code class=\"highlighter-rouge\">paypal.payment.execute<\/code> function provided by PayPal\u2019s Node SDK. This function takes three arguments: a payment ID, a JSON blob with <a href=\"https:\/\/developer.paypal.com\/docs\/api\/payments\/#payment_execute_request\">a few fields describing the payment to be executed<\/a>, and a callback that is run on success or fail. When PayPal redirects to our endpoint, it modifies the query parameters of the redirect URL, adding a <code class=\"highlighter-rouge\">paymentId<\/code> and a <code class=\"highlighter-rouge\">PayerID<\/code>. These parameters must be used to execute the payment, with <code class=\"highlighter-rouge\">paymentId<\/code> corresponding to the first argument of <code class=\"highlighter-rouge\">paypal.payment.execute<\/code>, and <code class=\"highlighter-rouge\">PayerID<\/code> corresponding to a field within the JSON blob:<\/p>\n<pre><code>\r\nFile: payment_execution_ex.js\r\n-----------------------------\r\n\r\nserver.get(&#039;approvalComplete&#039;, function (req, res, next) {\r\n    console.log(&#039;User approved transaction&#039;);\r\n    executePayment(req.params);\r\n    res.send(200);\r\n});\r\n\r\nfunction executePaymentJson (payerId) {\r\n    return {\r\n        &quot;payer_id&quot;: payerId,\r\n        &quot;transactions&quot;: [{\r\n            &quot;amount&quot;: {\r\n                &quot;currency&quot;: &quot;USD&quot;,\r\n                &quot;total&quot;: &quot;1.00&quot;\r\n            }\r\n        }]\r\n    };\r\n}\r\n\r\nfunction executePayment(params) {\r\n     console.log(&#039;Executing an Approved Payment&#039;);\r\n\r\n    \/\/ Appended to the URL by PayPal during the approval step.\r\n    let paymentId = parameters.paymentId;\r\n    let payerId = parameters.PayerID;\r\n\r\n    \/\/ Generate the sample payment execution JSON that paypal requires:\r\n    let paymentJson = executePaymentJson(payerId)\r\n\r\n    \/\/ Finally, execute the payment, and tell the user that we got their payment.\r\n    paypal.payment.execute(paymentId, paymentJson, function (error, payment) {\r\n        if (error) {\r\n            console.log(error.response);\r\n            throw error;\r\n        } else {\r\n            console.log(&#039;Payment Executed Successfully&#039;);\r\n            \/\/ TODO: Inform the user on their bot channel.\r\n        }\r\n    });\r\n};\r\n<\/code><\/pre>\n<p>We now have the full payment flow, except the very last step which involves informing the user (via the bot, and on the user\u2019s native messaging channel) that their payment has been successfully processed. Since we\u2019re no longer operating within the context of the bot, but rather within the context of the HTTP server, we\u2019ll have to get creative.<\/p>\n<p>We\u2019ll need to modify our code a bit and build up an <code class=\"highlighter-rouge\">Address<\/code>, a Bot Framework model that identifies the channel and user with which a message is associated. These properties are all encoded on the <code class=\"highlighter-rouge\">session.message<\/code> object normally, and can thus be re-encoded as query arguments in the <code class=\"highlighter-rouge\">return_url<\/code> of the approval step. PayPal does not strip these parameters, so they get returned again when the user is redirected to the <code class=\"highlighter-rouge\">approvalComplete<\/code> endpoint. When the payment is executed, we can pass these parameters along and create a message to be sent to the user, even in the context of the HTTP Server, without an active <code class=\"highlighter-rouge\">session<\/code> object.<\/p>\n<pre><code>\r\nFile: redirect_bot_message_ex.js\r\n--------------------------------\r\n\r\nfunction createReturnUrl (address) {\r\n    console.log(&#039;Creating Return Url&#039;);\r\n\r\n    \/\/ The address passed in is an Object that defines the context\r\n    \/\/ of the conversation - the user, the channel, the http endpoint the bot\r\n    \/\/ exists on, and so on. We encode this information into the return URL\r\n    \/\/ to be parsed out by our approval completion endpoint.\r\n    let addressEncoded = encodeURIComponent(JSON.stringify(address));\r\n\r\n    \/\/ This object encodes the endpoint that PayPal redirects to when.\r\n    \/\/ a user approves the transaction.\r\n    let urlObject = {\r\n        protocol: &#039;http&#039;,\r\n        hostname: &#039;localhost&#039;,\r\n        port: configuration.PORT,\r\n        pathname: &#039;approvalComplete&#039;,\r\n        query: addressEncoded\r\n    }\r\n\r\n    return url.format(urlObject);\r\n}\r\n\r\nfunction executePayment (parameters) {\r\n    console.log(&#039;Executing an Approved Payment&#039;);\r\n\r\n    \/\/ Appended to the URL by PayPal during the approval step.\r\n    let paymentId = parameters.paymentId;\r\n    let payerId = parameters.PayerID;\r\n\r\n    \/\/ Generate the sample payment execution JSON that paypal requires:\r\n    let paymentJson = executePaymentJson(payerId)\r\n\r\n    \/\/ Grab the encoded address object, URL decode it, and parse it back into a JSON object.\r\n    let addressEncoded = decodeURIComponent(parameters.addressEncoded);\r\n    let address = JSON.parse(addressEncoded);\r\n\r\n    \/\/ Finally, execute the payment, and tell the user that we got their payment.\r\n    paypal.payment.execute(paymentId, paymentJson, function (error, payment) {\r\n        if (error) {\r\n            console.log(error.response);\r\n            throw error;\r\n        } else {\r\n            console.log(&#039;Payment Executed Successfully&#039;);\r\n            respondToUser(payment, address);\r\n        }\r\n    });\r\n}\r\n\r\nfunction respondToUser (payment, address) {\r\n    let message = new builder.Message().address(address).text(&#039;Thanks for your payment!&#039;);\r\n\r\n    \/\/ Asks the bot to send the message we built up above to the user.\r\n    bot.send(message.toMessage());\r\n}\r\n\r\nbot.dialog(&#039;listFines&#039;, [\r\n    function (session, args) {\r\n        console.log(&#039;List Fines Dialog&#039;);\r\n        session.send(&#039;You have 1 outstanding fine:&#039;);\r\n\r\n        session.send(&#039;Parking Fine Violation&#039;);\r\n        builder.Prompts.choice(session, &quot;What would you like to do?&quot;, [&quot;Pay fine&quot;, &quot;Cancel&quot;]);\r\n    },\r\n    function (session, results, next) {\r\n        let choice = results.response;\r\n\r\n        if (choice.entity === &#039;Cancel&#039;) {\r\n            return;\r\n        }\r\n\r\n        \/\/ Starts the payment flow.\r\n        createAndSendPayment(session);\r\n    },\r\n]);\r\n\r\n\r\n<\/code><\/pre>\n<p><a href=\"https:\/\/gist.github.com\/bnookala\/a8c8c352e4c6180e822655fa311aa204#file-redirect_bot_message_ex-js-L8\">Line 8<\/a> identifies the <code class=\"highlighter-rouge\">Address<\/code> of the message to be encoded into the <code class=\"highlighter-rouge\">return_url<\/code>. When the payment is executed, <a href=\"https:\/\/gist.github.com\/bnookala\/a8c8c352e4c6180e822655fa311aa204#file-redirect_bot_message_ex-js-L34-L35\">lines 34-35<\/a> pull these same encoded parameters out of the query string, and pass it along to a new function, <code class=\"highlighter-rouge\">respondToUser<\/code>, which uses the address to build up a <code class=\"highlighter-rouge\">builder.Message<\/code>. All messages that pass through the Bot Framework are represented internally through this model. Thus, we can create a response here, and send it along to our bot at <a href=\"https:\/\/gist.github.com\/bnookala\/a8c8c352e4c6180e822655fa311aa204#file-redirect_bot_message_ex-js-L53\">line 53<\/a>. Our complete interaction now looks like this:<\/p>\n<p> <img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/cse\/wp-content\/uploads\/sites\/55\/2016\/10\/complete_flow.gif\" alt=\"Image complete flow\" width=\"789\" height=\"492\" class=\"aligncenter size-full wp-image-11093\" \/><\/p>\n<h2 id=\"conclusion\">Conclusion<\/h2>\n<p>The code highlighted above consists mostly of snippets and examples that intend to illustrate how we implemented payments with Bot Framework. A working code example is <a href=\"https:\/\/github.com\/bnookala\/node-paymentbot\">available on GitHub<\/a>.<\/p>\n<p>Through this tutorial, I\u2019ve identified a common third party service integration, PayPal, and integrated it with a Bot built on Bot Framework\u2019s Node SDK. I\u2019ve also demonstrated that Bot Framework is a flexible tool for integrating conversation into your platform and can coexist with many popular existing integrations.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Integrating payment service providers with the Microsoft Bot Framework.<\/p>\n","protected":false},"author":21355,"featured_media":11095,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[13,16],"tags":[108,110,249,275,289],"class_list":["post-2128","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-bots","category-devops","tag-bot-builder-for-node-js","tag-bots","tag-microsoft-bot-framework-mbf","tag-node","tag-paypal"],"acf":[],"blog_post_summary":"<p>Integrating payment service providers with the Microsoft Bot Framework.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/posts\/2128","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/users\/21355"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/comments?post=2128"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/posts\/2128\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/media\/11095"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/media?parent=2128"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/categories?post=2128"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/tags?post=2128"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}