Skip to main content

Webhook

Receive n1co business events on your webhook hotspot

Listen for events from your n1co business account at your webhook connection point so your integration can trigger automatic reactions as events occur in your account.

Why use webhooks

When creating integrations with n1co Business, you may want your applications to receive events as they occur in your account, so that your back-end systems can execute the necessary actions.

To enable webhook events, you must register webhook connection points. After registering them, n1co Business can send real-time event data to your application's connection point when events occur. n1co Business uses HTTPS to send webhook events to your application as a JSON payload that includes an event object.

Receiving webhook events is particularly useful for listening to asynchronous events, for example, when an order is created, paid or cancelled, when the shipping status of an order is updated, etc.

Webhook configuration

To set up a webhook hotspot, you must provide a hotspot URL and generate a secret key. The connection point URL is the URL to which n1co Business will send webhook events. The secret key is a string used to sign webhook events that are sent to your application. You can use the secret key to verify that the events you receive are coming from n1co Business.

Creating a webhook connection point

To create a webhook connection point, follow these steps:

  1. Log in to your n1co business account
  2. In the menu on the top right, click Settings
  3. In the Options for developers section, click Webhook
  4. Add your webhook hotspot URL and generate a secret key, then click Save Changes.
  5. You are done! Your webhook hotspot is ready to receive events from n1co business

Webhook events

n1co Business sends webhook events to your connection point in real time. Each webhook event includes an event object that contains information about the event that occurred in your n1co Business account. Webhook events events are sent as JSON payloads in an HTTPS POST request to your connection point.

Event object

The contract for webhook events is as follows:

{
"orderId": "String!",
"orderReference": "String",
"description": "String!",
"level": "String!",
"type": "String!",
"metadata": "Object"
}

The definition of the fields of the event object is as follows:

orderId: String! -> internal identifier of the order generated by the n1co system
orderReference: String -> order reference provided by the integrator
description: String! -> event description message
level: String! -> severity level of the event
type: String! -> event type
metadata: Object -> key-value object containing additional information about event

Severity Levels level

  • Info: Indicates general information or events that do not require immediate attention.
  • Warning: Indicates situations that may require attention or investigation, but do not represent a critical error or system failure.
  • Error: Indicates a system error that requires attention.

Event types type

Created

This event indicates that a new order has been created in n1co business.

Example:

{
"orderId": "1057",
"orderReference": "test-3",
"description": "La orden fue creada",
"metadata": null,
"level": "Info",
"type": "Created"
}
SuccessPayment

This event indicates that the payment of an order has been successful.

Example:

{
"orderId": "52544",
"orderReference": null,
"description": "La orden fue pagada exitosamente autorización: 831000",
"metadata": {
"PaymentId": "3aaf6eaf-f32f-4857-8312-e63f4e497822",
"ChargeId": "af543e17-18d9-4512-b1ba-2991b6c31613",
"Status": "SUCCEEDED",
"AuthorizationCode": "831000",
"SequentialNumber": "7744791861156741504807",
"AccountId": "hugoapp.h4b",
"PaymentProcessor": "cybersource",
"PaymentProcessorReference": "7744791861156741504807",
"TransactionDate": "2026-03-25T22:53:06.6475595Z",
"PaidAmount": "8.00",
"BuyerName": "Robert c:",
"BuyerPhone": "+50495363424",
"BuyerEmail": "[email protected]",
"BuyerExternalId": "6x1ekkKH1a",
"CheckoutNote": "N/A",
"OrderReference": "",
"OrderTotalDetails": {
"subtotal": "8.0000",
"shippingAmount": "0",
"discountAmount": "0",
"surchargeAmount": "0",
"total": "8.00"
},
"IsManagedPaymentMethod": false,
"InvoiceName": "",
"InvoiceAddress": "",
"InvoiceTaxCode": "",
"orderDetail": [
{
"orderItemId": "13188",
"itemId": "30666",
"name": "Coconut Shrimp",
"price": "8.0000",
"promoId": null,
"promoPrice": null,
"promoName": null,
"quantity": "1",
"modifiersTotal": "0.0000",
"sku": "DL100",
"productImageUrl": "https://cdn.h4b.dev/images/.../Image1.webp",
"modifiers": [],
"note": null,
"description": "8 Camarones empanizados con coco rallado...",
"quantityAvailable": "75",
"requiresShipping": false,
"productMetadata": null,
"coupon": {
"code": "U6FWUW",
"qrCodeUrl": "https://qr.n1co.shop/?chl=U6FWUW",
"startDate": "2026-01-06T18:00:00",
"endDate": "2026-03-31T18:00:00",
"redemptionLimit": "1",
"redemptionCount": "0",
"status": "Unredeemed"
}
}
]
},
"level": "Info",
"type": "SuccessPayment"
}
metadata fields in SuccessPayment
FieldTypeDescription
PaymentIdStringUnique payment identifier
ChargeIdStringUnique charge identifier
StatusStringPayment status (SUCCEEDED)
AuthorizationCodeStringTransaction authorization code
SequentialNumberStringTransaction sequential number
AccountIdStringMerchant account identifier
PaymentProcessorStringPayment processor used
PaymentProcessorReferenceStringPayment processor reference
TransactionDateStringTransaction date and time (ISO 8601)
PaidAmountStringAmount paid
BuyerNameStringBuyer's name
BuyerPhoneStringBuyer's phone number
BuyerEmailStringBuyer's email
BuyerExternalIdStringBuyer's external identifier
CheckoutNoteStringCheckout note
OrderReferenceStringOrder reference provided by the integrator
OrderTotalDetailsObjectOrder totals breakdown (subtotal, shippingAmount, discountAmount, surchargeAmount, total)
IsManagedPaymentMethodBooleanIndicates if the payment method is managed by n1co
InvoiceNameStringBilling name
InvoiceAddressStringBilling address
InvoiceTaxCodeStringTax code for billing
orderDetailArrayOrder product details (see table below)
Product details orderDetail
FieldTypeDescription
orderItemIdStringOrder item identifier
itemIdStringProduct identifier
nameStringProduct name
priceStringProduct unit price
promoIdString | nullApplied promotion identifier
promoPriceString | nullPromotional price
promoNameString | nullPromotion name
quantityStringProduct quantity
modifiersTotalStringTotal of applied modifiers
skuStringProduct SKU
productImageUrlStringProduct image URL
modifiersArrayList of modifiers applied to the product
noteString | nullProduct note
descriptionStringProduct description
quantityAvailableStringAvailable inventory quantity
requiresShippingBooleanIndicates if the product requires shipping
productMetadataObject | nullAdditional product metadata
couponObject | nullCoupon associated with the product (see table below). Is null if the product has no coupon
coupon object

When a product has an associated coupon, the coupon field contains the coupon information generated for that purchase.

FieldTypeDescription
codeStringCoupon code
qrCodeUrlStringQR code URL for the coupon
startDateStringCoupon validity start date (ISO 8601)
endDateStringCoupon expiration date (ISO 8601)
redemptionLimitStringMaximum number of times the coupon can be redeemed
redemptionCountStringNumber of times the coupon has been redeemed
statusStringCurrent coupon status

Possible coupon statuses (status):

  • Unredeemed: The coupon is active and available for redemption
  • Redeemed: The coupon has reached its redemption limit
  • Expired: The coupon has expired (current date is past endDate)
  • Scheduled: The coupon is not yet active (current date is before startDate)
Cancelled

This event indicates that an order has been cancelled.

Example:

{
"orderId": "32395",
"orderReference": null,
"description": "La orden fue cancelada, motivo: some reason",
"metadata": null,
"level": "Info",
"type": "Cancelled"
}
Finalized

This event indicates that an order has been finalized.

Ejemplo:

{
"orderId": "32395",
"orderReference": null,
"description": "Se finalizó la orden.",
"metadata": null,
"level": "Info",
"type": "Finalized"
}
Updated

This event indicates that the shipping status of an order in n1co business has been updated.

List of shipping statuses:

  • PENDING: Order pending
  • ACCEPTED: Order accepted
  • READY: Order ready
  • DISPATCHED: Order dispatched
  • ON_ITS_WAY: Order on the way
  • DELIVERED: Order delivered
  • SCHEDULED: Scheduled order
  • REJECTED: Order rejected

Examples:

For status change from PENDING to ACCEPTED:

{
"orderId": "13766",
"orderReference": null,
"description": "Se cambió el estado del envío de Pendiente a Aceptado",
"metadata": {
"PreparationEtaMinutes": "15",
"PreviousStatus": "PENDING",
"NewStatus": "ACCEPTED"
},
"level": "Info",
"type": "Updated"
}

For the change of status from ACCEPTED to READY:

{
"orderId": "13766",
"orderReference": null,
"description": "Se cambió el estado del envío de Aceptado a Preparado",
"metadata": {
"PreviousStatus": "ACCEPTED",
"NewStatus": "READY"
},
"level": "Info",
"type": "Updated"
}

For the status change from READY to DISPATCHED:

{
"orderId": "13766",
"orderReference": null,
"description": "Se cambió el estado del envío de Preparado a Despachado",
"metadata": {
"PreviousStatus": "READY",
"NewStatus": "DISPATCHED"
},
"level": "Info",
"type": "Updated"
}

For the status change from DISPATCHED to ON_ITS_WAY:

{
"orderId": "13766",
"orderReference": null,
"description": "Se cambió el estado del envío de Despachado a En Camino",
"metadata": {
"PreviousStatus": "DISPATCHED",
"NewStatus": "ON_ITS_WAY"
},
"level": "Info",
"type": "Updated"
}

For the change of status from ON_ITS_WAY to DELIVERED:

{
"orderId": "13766",
"orderReference": null,
"description": "Se cambió el estado del envío de En Camino a Entregado",
"metadata": {
"PreviousStatus": "ON_ITS_WAY",
"NewStatus": "DELIVERED"
},
"level": "Info",
"type": "Updated"
}
Deleted

This event indicates that an order has been deleted.

Example:

{
"orderId": "32395",
"orderReference": null,
"description": "Se eliminó la orden",
"metadata": null,
"level": "Info",
"type": "Deleted"
}
SuccessReverse

This event indicates that a payment reversal was successful.

Example:

{
"orderId": "1056",
"orderReference": null,
"description": "El pago de la orden fue revertido",
"metadata": null,
"level": "Info",
"type": "SuccessReverse"
}
ReverseError

This event indicates that an error occurred while attempting to reverse a payment.

Example:

{
"orderId": "1056",
"orderReference": null,
"description": "La orden no pudo ser cancelada, no se pudo revertir el pago",
"metadata": null,
"level": "Error",
"type": "ReverseError"
}
PaymentError

This event indicates that an error occurred while attempting to make a payment.

Example:

{
"orderId": "1056",
"orderReference": null,
"description": "El pago no fue realizado: some error",
"metadata": null,
"level": "Error",
"type": "PaymentError"
}
ThreeDSecureAuthSucceeded

This event indicates that the 3DS authentication was successfully completed for a specific collection and therefore you can proceed with the transaction confirmation using the authenticationId provided in the metadata of the event.

Example:

{
"orderId": "31833",
"orderReference": "order-integration-id",
"description": "La autenticación 3DS ha sido completada con éxito",
"metadata": {
"authenticationId": "fdedee2f-5942-47ff-83a5-cb473d0e8764"
},
"level": "Info",
"type": "ThreeDSecureAuthSucceeded"
}
ThreeDSecureAuthError

This event indicates that an error occurred during 3DS authentication for a specific charge. The error may be due to several reasons, such as incorrect cardholder information, technical problems with the 3DS authentication provider, or connectivity issues. Further details can be found in the reason and description attributes included in the metadata of the event.

Example:

{
"orderId": "31833",
"orderReference": "order-integration-id",
"description": "Ocurrió un error en la autenticación 3DS",
"metadata": {
"authenticationId": "fdedee2f-5942-47ff-83a5-cb473d0e8764",
"reason" : "Some reason",
"description" : "Some description",
},
"level": "Error",
"type": "ThreeDSecureAuthError"
}
ThreeDSecureAuthExpired

This event is an indicator that the 3DS authentication was not completed on time and the transaction cannot be completed at this time. The transaction can be reattempted later once the cardholder initiates a new authentication request.

Example:

{
"orderId": "31833",
"orderReference": "order-integration-id",
"description": "La autenticación 3DS ha expirado",
"metadata": {
"authenticationId": "fdedee2f-5942-47ff-83a5-cb473d0e8764"
},
"level": "Info",
"type": "ThreeDSecureAuthExpired"
}
ThreeDSecureAuthFailed

This event indicates that there was a technical failure that prevented 3DS authentication from completing successfully for a specific request. The failure may be due to problems with the 3DS authentication provider, integration issues, or server-side issues. Further details can be found in the reason and description attributes included in the metadata of the event.

Example:

{
"orderId": "31833",
"orderReference": "order-integration-id",
"description": "Ocurrió un fallo en la autenticación 3DS",
"metadata": {
"authenticationId": "fdedee2f-5942-47ff-83a5-cb473d0e8764",
"reason" : "Some reason",
"description" : "Some description",
},
"level": "Error",
"type": "ThreeDSecureAuthFailed"
}

Verification of webhook events

To verify that the webhook events you receive are coming from n1co buiness, you can use the secret key that you generated when you set up your webhook connection point. To verify a webhook event, follow these steps:

  1. Extract the value of the X-H4B-Hmac-Sha256 header from the HTTP POST request containing the webhook event.
  2. Calculate the HMAC SHA-256 of the HTTP POST request body using the secret key generated when you set up your webhook.

Example of webhook event verification

Node.js
app.post("/webhook", (req, res) => {
//Llave secreta configurada en el administrador de n1co Business
const API_SECRET = process.env.API_SECRET;

//Extraer el valor del header X-H4B-Hmac-Sha256'
const hmacHeader = req.get("X-H4B-Hmac-Sha256");

const content = /* body del request como strings */ req.body;

//Generar el hash
const hash = crypto
.createHash("sha256", API_SECRET)
.update(content, "utf8", "hex")
.digest("base64");

if (hash === hmacHeader) {
console.log("Notification Request from n1co Business received", body);
res.sendStatus(200);
} else {
console.log("Could not validate signature", hash);
res.sendStatus(400);
}
});
Python
import hashlib
import hmac
from flask import Flask, request, abort

app = Flask(__name__)

@app.route("/webhook", methods=['POST'])
def webhook():
# Llave secreta configurada en el administrador de n1co Business
API_SECRET = os.environ.get('API_SECRET')

# Extraer el valor del header 'X-H4B-Hmac-Sha256'
hmac_header = request.headers.get('X-H4B-Hmac-Sha256')

# body del request como strings
content = request.data.decode('utf-8')

# Generar el hash
hash = hmac.new(API_SECRET.encode('utf-8'), content.encode('utf-8'), hashlib.sha256).hexdigest()

if hmac.compare_digest(hash, hmac_header):
print("Notification Request from n1co Business received", content)
return '', 200
else:
print("Could not validate signature", hash)
abort(400)

if __name__ == '__main__':
app.run()
PHP

<?php

// Llave secreta configurada en el administrador de n1co Business
const API_SECRET = getenv("API_SECRET");

// Extraer el valor del header X-H4B-Hmac-Sha256'
$hmacHeader = $_SERVER["HTTP_X_H4B_HMAC_SHA256"];

// Body del request como strings
$content = file_get_contents("php://input");

// Generar el hash
$hash = hash_hmac("sha256", $content, API_SECRET);

if ($hash === $hmacHeader) {
echo "Notification Request from n1co Business received";
http_response_code(200);
} else {
echo "Could not validate signature";
http_response_code(400);
}

?>