{"metadata":{"image":[],"title":"","description":""},"api":{"url":"","auth":"required","results":{"codes":[]},"params":[],"method":"get"},"next":{"description":"","pages":[]},"title":"Webhooks","type":"basic","slug":"webhooks","excerpt":"","body":"You can receive automated notifications of events in Apruve via webhooks.\n\n# How Apruve Uses Webhooks\n\nWhen a `webhook_url` is specified on a Merchant's profile, Apruve will POST a JSON document to that URL when the status of an item changes. Apruve expects a 200 response from this POST. **If a 200 is not received, we will keep trying (with exponentially increasing delay) for 24 hours.**\n\nThe status changes that will trigger a Webhook call are:\n\n* Invoice Closed\n* Invoice Funded\n* Invoice Canceled\n* Order Accepted\n* Order Canceled\n* Payment Term Accepted\n* Shipment Created\n* Shipment Updated\n* Corporate Account Approved\n* Team Member Added\n* Team Member Removed\n* Credit Available Updated\n\nThe JSON payload will contain the following information:\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"Field Name\",\n    \"h-1\": \"Data Type\",\n    \"h-2\": \"Comments\",\n    \"0-0\": \"`uuid`\",\n    \"1-0\": \"`created_at`\",\n    \"2-0\": \"`event`\",\n    \"3-0\": \"`entity`\",\n    \"4-0\": \"`status`\",\n    \"5-0\": \"`links`\",\n    \"0-1\": \"String\",\n    \"1-1\": \"Date\",\n    \"2-1\": \"String\",\n    \"3-1\": \"JSON\",\n    \"4-1\": \"String\",\n    \"5-1\": \"URL\",\n    \"5-2\": \"The URL for the item from the Apruve API. This URL may be used as a unique identifier for the resource, and/or to fetch the item from the API.\",\n    \"4-2\": \"The current status of the item being updated.\",\n    \"3-2\": \"A JSON representation of the subject of the webhook notification (Invoice, Order, or Payment Term).\",\n    \"2-2\": \"The type of event that prompted the webhook call. An example is \\\"payment_term.accepted\\\".\",\n    \"1-2\": \"The timestamp of the webhook request.\",\n    \"0-2\": \"A unique ID that can be used to track the messages you've processed.\"\n  },\n  \"cols\": 3,\n  \"rows\": 6\n}\n[/block]\n**Example Webhook Payload:**\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"{\\n    \\\"uuid\\\":\\\"abcdefghi\\\",\\n    \\\"created_at\\\":\\\"2016-08-18T10:36:54-05:00\\\",\\n    \\\"event\\\":\\\"payment_term.accepted\\\",\\n    \\\"entity\\\": \\n    {\\n        \\\"po_number\\\":\\\"abcdefghi\\\",\\n        \\\"type\\\":\\\"CorporateAccount\\\",\\n        \\\"status\\\":\\\"approved\\\",\\n        \\\"escalated_at\\\":null,\\n        \\\"final_state_at\\\":null,\\n        \\\"links\\\":\\n        {\\n            \\\"order\\\":\\\"https://test.apruve.com/api/v4/orders/jklmnopqr\\\"\\n        }\\n    }\\n}\",\n      \"language\": \"json\"\n    }\n  ]\n}\n[/block]\nEach Webhook has a unique UUID that identifies it. If you have trouble with a Webhook, this would be helpful information to include in a support request.\n\n## Digital Signature\n\nEvery Apruve webhook contains a SHA256/RSA digital signature of the webhook's contents.  If the signature can be verified\nusing Apruve's public key, you can be certain that the webhook contents were generated by Apruve and have not been\ntampered with. To verify a webhook, you need the following three pieces of information:\n\n1. The signature itself. This can be found in the `X-Apruve-Signature` HTTP header included in every Apruve webhook request.\n2. Apruve's public key. You can get this value interactively via Apruve's Public Key API.\n3. The raw, unparsed body of the webhook.\n\nThe specific procedure for verifying the signature will vary based on your platform's underlying technology. If your platform\ndoes not provide libraries that provide signature verification services, OpenSSL provides command line tools that can.\n\nRuby Example:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"apruve_public_key = OpenSSL::PKey.read(Apruve::Client.get('public_key.txt').body)\\nverified = apruve_public_key.verify(\\n                  OpenSSL::Digest::SHA256.new,\\n                  Base64.decode64(webhook.headers['X-Apruve-Signature']),\\n                  webhook.body)\",\n      \"language\": \"ruby\"\n    }\n  ]\n}\n[/block]\n \n# Apruve Webhook Best Practices\n\nTo promote the best security in your Apruve webhook notification service, we recommend following these best practices:\n\n* Use SSL/HTTPS in the URL you provide for your webhook service.\n* Verify the request signature.\n* Create a mechanism to guarantee that only Apruve will know the correct URL. Perhaps the best way to do this would be to generate a long, random token (sometimes referred to as an API-key, GUID, or UUID) that is specified as part of the callback URL you provide to Apruve. When you receive the webhook POST, you should authenticate this token and verify that it is valid.\n* You can also query Apruve using the api_url and verify that the status is correct, rather than trusting the data you receive on the webhook call. For the absolute highest level of security, use the api_url that you received in the HTTP response when you created the original payment.\n\nTaking these steps will ensure that only Apruve is authenticated and authorized to trigger a status update in your system.\n\n# Webhooks\n\n## Webhook - invoice.closed\n\n### Overview\nThis webhook event is sent to your webhook endpoint when an invoice is closed. The entire invoice is sent as the payload in this webhook. Once an invoice is closed, it has been paid. If you have been waiting for payment before you deliver, now would be the time to trigger that.\n\nSee the example webhook payload above.\n\n## Webhook - invoice.funded\n\n### Overview\nThis webhook event is sent to your webhook endpoint when an invoice is funded. The entire invoice is sent as the payload in this webhook. Once an invoice is funded, the merchant has been paid out, and the creditor is expecting payment. No further action should be necessary by the merchant.\n\nSee the example webhook payload above.\n\n## Webhook - invoice.canceled\n\n### Overview\nThis webhook event is sent to your webhook endpoint when an invoice is canceled. The entire invoice is sent as the payload in this webhook. Once an invoice is canceled, it has been withdrawn by the merchant.\n\nSee the example webhook payload above.\n\n## Webhook - order.accepted\n\n### Overview\nThis webhook event is sent to your webhook endpoint when an order is accepted. The entire order is sent as the payload in this webhook. For many situations, order Acceptance is the event to be used to decide when to ship a product or deliver a service.\n\nSee the example webhook payload above.\n\n## Webhook - order.canceled\n\n### Overview\nThis webhook event is sent to your webhook endpoint when an order is canceled. The entire order is sent as the payload in this webhook. If an order is canceled, it should not be delivered as no payment will be possible.\n\nSee the example webhook payload above.\n\n## Webhook - payment_term.accepted\n\n### Overview\n(deprecated) This webhook event is sent to your webhook endpoint when a payment_term is accepted. The entire payment_term is sent as the payload in this webhook. \nOnce a payment_term is accepted, that means that a contract for payment is established, in most industries this would trigger fulfillment of your product.\n\nSee the example webhook payload above.\n\n## Webhook - shipment.created\n\n### Overview\nThis webhook event is sent to your webhook endpoint when a shipment is created. The entire shipment is sent\nas the payload in this webhook. A shipment is always associated with an invoice, and may contain all or some of the items\nfrom the invoice that have been shipped. A shipment which fulfills all invoice totals will be in a 'fulfilled' status,\nwhile a partial shipment will return a 'partial' status.\n\nSee the example webhook payload above.\n\n## Webhook - shipment.updated\n\n### Overview\nThis webhook event is sent to your webhook endpoint when a shipment is updated. The entire shipment is sent\nas the payload in this webhook. An updated shipment may contain an updated tracking number, shipping_cents amount or\nstatus as indicated by which subset of invoice items have been fulfilled.\n\nSee the example webhook payload above.\n\n## Webhook - corporate_account.approved\n\n### Overview\nThis webhook event is sent to your webhook endpoint when a corporate account is approved with a credit limit. The entire corporate account is sent as the payload in this webhook.\n\nSee the example webhook payload above.\n\n\n## Webhook - team_member.added\n\n### Overview\nThis webhook event is sent to your webhook endpoint when a team member is added to one of your corporate accounts.\nInformation about the team member, including their roles and the uuid of their corporate account, is sent with this webhook.\n\nSee the example webhook payload above.\n\n## Webhook - team_member.removed\n\n### Overview\nThis webhook event is sent to your webhook endpoint when a team member is removed fromone of your corporate accounts.\nInformation about the team member, including their roles and the uuid of their corporate account, is sent with this webhook.\n\nSee the example webhook payload above.\n\n## Webhook - credit_limit.updated\n\n### Overview\nThis webhook event is sent to your webhook endpoint when the available credit is updated.\nInformation about the credit limit and corporate account is sent with this webhook.\n\nSee the example webhook payload above.","updates":[],"order":6,"isReference":false,"hidden":false,"sync_unique":"","link_url":"","link_external":false,"_id":"598362cd5de0a1002049efa9","project":"58b9e955fba7da250056ff86","version":{"version":"4.0","version_clean":"4.0.0","codename":"","is_stable":true,"is_beta":false,"is_hidden":false,"is_deprecated":false,"categories":["58b9e955fba7da250056ff8a","58b9e9e168a4a5190011dcc2","58b9ea1de87271190074c623","58b9f9df4022e60f00ae20af","58bda4f77181082500275455","58bda69b8bcd092f00e52862","58bda751b4e9640f00e4bdaf","58e800fabc0deb0f002801f3","5925bfd9504e5239003807f4","5925c026aef9fd27008525c0","5925c0e7dd71b51b00ccc329","592d872451a3e80f00eb4a1a","592d9539b9b6b91900569ea0","592d990a51a3e80f00eb4c25","592d9bf480832f0f00ddfa46","592d9d5051a3e80f00eb4e02","592dbd5cd97832190073d76a","598360d76050430034ef4e07","598363237c926c0028d2e420","598363755de0a1002049efad","598363c27c926c0028d2e442","59c15f2ebc639a0032f770f0"],"_id":"58b9e955fba7da250056ff89","releaseDate":"2017-03-03T22:08:21.880Z","__v":22,"createdAt":"2017-03-03T22:08:21.880Z","project":"58b9e955fba7da250056ff86"},"category":{"sync":{"isSync":false,"url":""},"pages":[],"title":"Developer Resources","slug":"developer-resources-1","order":2,"from_sync":false,"reference":false,"_id":"598360d76050430034ef4e07","project":"58b9e955fba7da250056ff86","version":"58b9e955fba7da250056ff89","isAPI":false,"createdAt":"2017-08-03T17:43:51.991Z","__v":0},"user":"596f95a2be66bb002e66a935","createdAt":"2017-08-03T17:52:13.816Z","githubsync":"","__v":0,"parentDoc":null,"updatedAt":"2019-05-17T20:52:04.514Z"}
You can receive automated notifications of events in Apruve via webhooks. # How Apruve Uses Webhooks When a `webhook_url` is specified on a Merchant's profile, Apruve will POST a JSON document to that URL when the status of an item changes. Apruve expects a 200 response from this POST. **If a 200 is not received, we will keep trying (with exponentially increasing delay) for 24 hours.** The status changes that will trigger a Webhook call are: * Invoice Closed * Invoice Funded * Invoice Canceled * Order Accepted * Order Canceled * Payment Term Accepted * Shipment Created * Shipment Updated * Corporate Account Approved * Team Member Added * Team Member Removed * Credit Available Updated The JSON payload will contain the following information: [block:parameters] { "data": { "h-0": "Field Name", "h-1": "Data Type", "h-2": "Comments", "0-0": "`uuid`", "1-0": "`created_at`", "2-0": "`event`", "3-0": "`entity`", "4-0": "`status`", "5-0": "`links`", "0-1": "String", "1-1": "Date", "2-1": "String", "3-1": "JSON", "4-1": "String", "5-1": "URL", "5-2": "The URL for the item from the Apruve API. This URL may be used as a unique identifier for the resource, and/or to fetch the item from the API.", "4-2": "The current status of the item being updated.", "3-2": "A JSON representation of the subject of the webhook notification (Invoice, Order, or Payment Term).", "2-2": "The type of event that prompted the webhook call. An example is \"payment_term.accepted\".", "1-2": "The timestamp of the webhook request.", "0-2": "A unique ID that can be used to track the messages you've processed." }, "cols": 3, "rows": 6 } [/block] **Example Webhook Payload:** [block:code] { "codes": [ { "code": "{\n \"uuid\":\"abcdefghi\",\n \"created_at\":\"2016-08-18T10:36:54-05:00\",\n \"event\":\"payment_term.accepted\",\n \"entity\": \n {\n \"po_number\":\"abcdefghi\",\n \"type\":\"CorporateAccount\",\n \"status\":\"approved\",\n \"escalated_at\":null,\n \"final_state_at\":null,\n \"links\":\n {\n \"order\":\"https://test.apruve.com/api/v4/orders/jklmnopqr\"\n }\n }\n}", "language": "json" } ] } [/block] Each Webhook has a unique UUID that identifies it. If you have trouble with a Webhook, this would be helpful information to include in a support request. ## Digital Signature Every Apruve webhook contains a SHA256/RSA digital signature of the webhook's contents. If the signature can be verified using Apruve's public key, you can be certain that the webhook contents were generated by Apruve and have not been tampered with. To verify a webhook, you need the following three pieces of information: 1. The signature itself. This can be found in the `X-Apruve-Signature` HTTP header included in every Apruve webhook request. 2. Apruve's public key. You can get this value interactively via Apruve's Public Key API. 3. The raw, unparsed body of the webhook. The specific procedure for verifying the signature will vary based on your platform's underlying technology. If your platform does not provide libraries that provide signature verification services, OpenSSL provides command line tools that can. Ruby Example: [block:code] { "codes": [ { "code": "apruve_public_key = OpenSSL::PKey.read(Apruve::Client.get('public_key.txt').body)\nverified = apruve_public_key.verify(\n OpenSSL::Digest::SHA256.new,\n Base64.decode64(webhook.headers['X-Apruve-Signature']),\n webhook.body)", "language": "ruby" } ] } [/block] # Apruve Webhook Best Practices To promote the best security in your Apruve webhook notification service, we recommend following these best practices: * Use SSL/HTTPS in the URL you provide for your webhook service. * Verify the request signature. * Create a mechanism to guarantee that only Apruve will know the correct URL. Perhaps the best way to do this would be to generate a long, random token (sometimes referred to as an API-key, GUID, or UUID) that is specified as part of the callback URL you provide to Apruve. When you receive the webhook POST, you should authenticate this token and verify that it is valid. * You can also query Apruve using the api_url and verify that the status is correct, rather than trusting the data you receive on the webhook call. For the absolute highest level of security, use the api_url that you received in the HTTP response when you created the original payment. Taking these steps will ensure that only Apruve is authenticated and authorized to trigger a status update in your system. # Webhooks ## Webhook - invoice.closed ### Overview This webhook event is sent to your webhook endpoint when an invoice is closed. The entire invoice is sent as the payload in this webhook. Once an invoice is closed, it has been paid. If you have been waiting for payment before you deliver, now would be the time to trigger that. See the example webhook payload above. ## Webhook - invoice.funded ### Overview This webhook event is sent to your webhook endpoint when an invoice is funded. The entire invoice is sent as the payload in this webhook. Once an invoice is funded, the merchant has been paid out, and the creditor is expecting payment. No further action should be necessary by the merchant. See the example webhook payload above. ## Webhook - invoice.canceled ### Overview This webhook event is sent to your webhook endpoint when an invoice is canceled. The entire invoice is sent as the payload in this webhook. Once an invoice is canceled, it has been withdrawn by the merchant. See the example webhook payload above. ## Webhook - order.accepted ### Overview This webhook event is sent to your webhook endpoint when an order is accepted. The entire order is sent as the payload in this webhook. For many situations, order Acceptance is the event to be used to decide when to ship a product or deliver a service. See the example webhook payload above. ## Webhook - order.canceled ### Overview This webhook event is sent to your webhook endpoint when an order is canceled. The entire order is sent as the payload in this webhook. If an order is canceled, it should not be delivered as no payment will be possible. See the example webhook payload above. ## Webhook - payment_term.accepted ### Overview (deprecated) This webhook event is sent to your webhook endpoint when a payment_term is accepted. The entire payment_term is sent as the payload in this webhook. Once a payment_term is accepted, that means that a contract for payment is established, in most industries this would trigger fulfillment of your product. See the example webhook payload above. ## Webhook - shipment.created ### Overview This webhook event is sent to your webhook endpoint when a shipment is created. The entire shipment is sent as the payload in this webhook. A shipment is always associated with an invoice, and may contain all or some of the items from the invoice that have been shipped. A shipment which fulfills all invoice totals will be in a 'fulfilled' status, while a partial shipment will return a 'partial' status. See the example webhook payload above. ## Webhook - shipment.updated ### Overview This webhook event is sent to your webhook endpoint when a shipment is updated. The entire shipment is sent as the payload in this webhook. An updated shipment may contain an updated tracking number, shipping_cents amount or status as indicated by which subset of invoice items have been fulfilled. See the example webhook payload above. ## Webhook - corporate_account.approved ### Overview This webhook event is sent to your webhook endpoint when a corporate account is approved with a credit limit. The entire corporate account is sent as the payload in this webhook. See the example webhook payload above. ## Webhook - team_member.added ### Overview This webhook event is sent to your webhook endpoint when a team member is added to one of your corporate accounts. Information about the team member, including their roles and the uuid of their corporate account, is sent with this webhook. See the example webhook payload above. ## Webhook - team_member.removed ### Overview This webhook event is sent to your webhook endpoint when a team member is removed fromone of your corporate accounts. Information about the team member, including their roles and the uuid of their corporate account, is sent with this webhook. See the example webhook payload above. ## Webhook - credit_limit.updated ### Overview This webhook event is sent to your webhook endpoint when the available credit is updated. Information about the credit limit and corporate account is sent with this webhook. See the example webhook payload above.