Trigger a PayPal request when a Sales Order is released and automatically get back the payment.

The actors of the comedy:
Business Central Web hooks and APIs,
Azure Functions,
PayPal, Twilio and SendGrid SDKs.


Consider this request: when back-office approves an order in Business Central the customer shall be automatically notified with an email and an SMS. The email should contain the PayPal link. Finally, when the customer pays, Business Central’s order have to be automatically updated.

Although there is an embedded Paypal service connector and there are dozen of PayPal extensions on AppSource you might want to develop your custom PayPal connector to handle your customised payment processes. It’s just so easy to integrate it by using Web Hooks 🙂


  • When a Sales Order is being updated the subscribed Web Hook is invoked;
  • An Azure Function sends an email to the customer with a PayPal link to let the customer pay the order;
  • The Azure Function sends an SMS to alert the customer that the order is payable;
  • The customer proceed with payment using PayPal;
  • When the payment is completed or rejected the subscribed Web Hook is invoked and the result is notified to Business Central.;


The recipe is pretty easy and consists in a couple of ingredients:


A simple Azure Function works as subscriber for Business Central WebHook.

Here are sources in GitHub:

The Azure Function is in charge of the following tasks: asking Business Central API the order and customer detail, sending an SMS, creating on order on PayPal, sending an email with PayPal link to the customer.

SalesOrderPayPalWebHook.cs contains the azure function subscribed as Business Central WebHook. In my sample the WebHook is trigger every time a SalesOrder modification occurs.

Pay attention to these couple of lines of code, they are very important and this is the response the azure function must reply when you will subscribe your web hook in Business Central. Basically they response back the validation token to BC.

BusinessCentralConnector.cs contains class that manages calls to Business Central API. It connects to API and get the requested order and sales agent by applying filtering to API request.

PayPalConnector.cs contains class that manages calls to PayPal API. It posts to the Order API the json and gets back the order result.

MessageComposer.cs is the class that creates the response string used to send SMS and Email. The email contains the “PayPal Now” button.

MessageConnector.cs sends the email and the SMS to the customer. The SMS uses Twilio , the message uses SendGrid.

SalesOrders.cs and Customers.cs are the class representing Business Central SalesOrders and Customers tables. They are used for deserialising API data. I find useful to automatically convert Json returned from BC API to C# class. Just pay attention to DateTimeOffset field type that are not supported by JSON.

PayPalOrder.cs and PayPalResponseOrder.cs are the class representing PayPal Order and Order Response entities.

AzPayPal.cs produces the web page the user opens when clicking in the payment email. It’s just the standard paypal button that opens the paypal website.

PayPalPaymentWebHook.cs is the azure function that manages the PayPal webhooks. When the user completes the payment paypal calls this function passing the transaction data. This function updates business central order and send a confirmation email.

To have your solution working just download sources, configure your Business Central endpoint and deploy it to your azure subscription.


There is brief but well written article about web hooks here:

And here:

I use Insomia to register a new web hook to subscribe to salesOrder table modifications. Basically you POST to your Business Central URL{your_business_central_instance}/sandbox/api/v1.0/subscriptions

a JSON content like this:

“notificationUrl”: “https:/{your_azurefunction_address}”,
“resource”: “/api/v1.0/companies({your_company_id})/salesOrders”,
“clientState”: “optionalValueOf250”

If the azure function is working you get a confirmation reply:

“@odata.context”: “{your_bc_instance}/sandbox/api/v1.0/$metadata#subscriptions/$entity”,
“@odata.etag”: “W/”JzQ0O1djTE9JamVYVk0yMDYxc0dwRElCT1lPQlAwOHVISSsyeG9Tem81RlJhUXc9MTswMDsn””,
“subscriptionId”: “39db02dc8ccf4fd59755d92a9080197c”,
“notificationUrl”: “https://{}/api/SalesOrderWebHook”,
“resource”: “api/v1.0/companies({your_company})/salesOrders”,
“userId”: “dc77101d-e4d4-4e42-84ae-68c54851c232”,
“lastModifiedDateTime”: “2020-04-12T08:04:53Z”,
“clientState”: “optionalValueOf250”,
expirationDateTime“: “2020-04-15T08:04:53Z”

You can check anytime your active web hooks subscribed with a simple API query:


I am confident everybody already use PayPal for payments. First of all you need a PayPal Business Account, then you can create your credentials from PayPal developer site.

In PayPal developer console create a new app and give it a name.

Finally you will get what you need: the Client ID and the Secret Key.

PayPal Payment flow:

Orders API V2 documentation:

Payment API V2 documentation:

Deprecated API V1 documentation:


Go in your paypal apps panel:

Insert your azure function url and save.


First of all you need to buy a Twilio phone number. Unfortunately some countries are not available when you buy a number, for example Italy is not. In my case I decided to buy a number from Belgium the subscription is 1€ per month and thanks to European Union roaming rules messages among EU countries are charged same price as national message.

In Twilio site you have a wide choice of numbers:

Then you have to register all destination numbers in Twilio.


An SMS nowadays might sound some kind of old-fashion manner to send a message. First thought you may have is: why don’t you use whatsapp, SMS is just such an old technology. It’s true but if you have have to deal with an international customer it’s not so obvious to use WhatsApp. In every region of the world you have different messaging platforms: WeChat in Asia, Line in Japan, KaKaoTalk in South Korea, Telegram is Middle East countries, Viber is former Russian countries. It’s a mess and I takes time to implement all of them. Instead SMS are working everywhere and they are just so easy to handle!


25th of April 2020

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s